2009-03-04 18 views
27

Ich würde gerne render :json verwenden, aber es scheint nicht so flexibel. Was ist der richtige Weg?render: Json akzeptiert keine Optionen

respond_to do |format| 
    format.html # index.html.erb 
    format.xml { render :xml => @things } 

    #This is great 
    format.json { render :text => @things.to_json(:include => :photos) } 

    #This doesn't include photos 
    format.json { render :json => @things, :include => :photos } 
end 

Antwort

39

Ich habe etwas ähnliches mit render :json getan. Dies ist, was für mich gearbeitet:

respond_to do |format| 
    format.html # index.html.erb 
    format.json { render :json => @things.to_json(:include => { :photos => { :only => [:id, :url] } }) } 
end 
+0

Danke, das hat mir auch geholfen. – swilliams

+0

Hat mir auch geholfen. +1 – sscirrus

1
format.json { render @things.to_json(:include => :photos) } 
34

Ich denke, dieser Artikel für Sie nützlich sein können - Rails to_json or as_json? von Jonathan Julian.

Der Hauptgedanke ist, dass Sie to_json in Controllern vermeiden sollten. Es ist viel flexibler, as_json-Methode in Ihrem Modell zu definieren.

Zum Beispiel:

In Ihrem Thing Modell

def as_json(options={}) 
    super(:include => :photos) 
end 

Und dann können Sie in Ihrem Controller schreiben nur

render :json => @things 
+0

Dies ist wahrscheinlich die beste Lösung für dieses Problem .. – giosakti

+2

Möchte tun 'super (options.merge (: include =>: Fotos))', um andere mögliche übergebene Optionen zu erhalten. Sie würden trotzdem alle ': include' Optionen überschreiben, aber die Logik zum Zusammenführen von Werten für diesen Schlüssel würde etwas komplizierter werden. –

+0

Mit 'super options.reverse_merge: include =>: fotos' würde es möglich sein, den" default ": include zu überschreiben. (Siehe [Hash # reverse_merge] (http://api.rubyonrails.org/classes/Hash.html#method-i-reverse_merge)) – Steve

1

bei Array, was ich getan ist

respond_to do |format| 
    format.html 
    format.json {render :json => {:medias => @medias.to_json, :total => 13000, :time => 0.0001 }} 
end 
3

Das Verwalten komplexer Hashes in Ihren Controllern wird schnell hässlich.

Mit Rails 3 können Sie ActiveModel :: Serializer verwenden. Siehe http://api.rubyonrails.org/classes/ActiveModel/Serialization.html

Wenn Sie etwas Nicht-Triviales tun, siehe https://github.com/rails-api/active_model_serializers. Ich empfehle, separate Serializer-Klassen zu erstellen, um zu vermeiden, dass Ihre Modelle überflutet werden und Tests einfacher werden.

class ThingSerializer < ActiveModel::Serializer 
    has_many :photos 
    attributes :name, :whatever 
end 

# ThingsController 
def index 
    render :json => @things 
end 

# test it out 
thing = Thing.new :name => "bob" 
ThingSerializer.new(thing, nil).to_json