2009-03-04 19 views
27

私はrender :jsonを使用したいと思いますが、それは柔軟ではないようです。これを行う正しい方法は何ですか?レンダリング:jsonはオプションを受け付けません

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 

答えて

39

私はrender :jsonと同様のことをしました。これは私のために働いていたものです:

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

ありがとう、これも私を助けました。 – swilliams

+0

私も助けてくれました。 +1 – sscirrus

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

私はこの記事があなたのために有用であることができますね - Rails to_json or as_json?ジョナサンジュリアンで。

コントローラでto_jsonを使用しないでください。モデルでas_jsonメソッドを定義する方がずっと柔軟です。例えば

:あなたのシングモデルで

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

そして、あなただけの

render :json => @things 
+0

これはおそらくこの問題の最良の解決策です。 – giosakti

+2

他の可能な渡されたオプションを保存するには、 'super(options.merge(:include =>:photos))'を実行してください。あなたはまだ ':include'オプションをオーバーライドしますが、そのキーの値をマージするロジックは少し複雑になります。 –

+0

'super options.reverse_merge:include =>:photos'を使うと、" default ":includeを上書きすることができます。 ([Hash#reverse_merge](http://api.rubyonrails.org/classes/Hash.html#method-i-reverse_merge)を参照してください) – Steve

1

配列の場合は、私が行っては

respond_to do |format| 
    format.html 
    format.json {render :json => {:medias => @medias.to_json, :total => 13000, :time => 0.0001 }} 
end 
であるあなたのコントローラに書くことができます
3

あなたのコントローラの複雑なハッシュを管理するのは醜いです。

Rails 3では、ActiveModel :: Serializerを使用できます。 http://api.rubyonrails.org/classes/ActiveModel/Serialization.html

あなたが何か重要なことをしているのであれば、 https://github.com/rails-api/active_model_serializersを参照してください。モデルを乱雑にするのを避け、テストを簡単にするために、別々のシリアライザクラスを作成することをお勧めします。

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