render: json n'accepte pas les options
-
03-07-2019 - |
Question
J'aimerais utiliser render: json
mais il semble que ce ne soit pas aussi flexible. Quelle est la bonne façon de faire cela?
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
La solution
J'ai fait quelque chose de similaire avec render: json
. C'est ce qui a fonctionné pour moi:
respond_to do |format|
format.html # index.html.erb
format.json { render :json => @things.to_json(:include => { :photos => { :only => [:id, :url] } }) }
end
Autres conseils
Je suppose que cet article peut vous être utile - Rails to_json ou as_json? de Jonathan Julian.
L'idée principale est d'éviter l'utilisation de to_json dans les contrôleurs. Il est beaucoup plus flexible de définir la méthode as_json dans votre modèle.
Par exemple:
Dans votre modèle Thing
def as_json(options={})
super(:include => :photos)
end
Ensuite, vous pouvez écrire dans votre contrôleur simplement
render :json => @things
La gestion des hachages complexes dans vos contrôleurs devient laide rapidement.
Avec Rails 3, vous pouvez utiliser ActiveModel :: Serializer. Voir http://api.rubyonrails.org/classes/ActiveModel/Serialization.html
Si vous faites quelque chose de non trivial, voir https://github.com/rails-api/active_model_serializers . Je recommande de créer des classes de sérialiseur distinctes pour éviter d'encombrer vos modèles et faciliter les tests.
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
format.json { render @things.to_json(:include => :photos) }
en cas de tableau ce que j'ai fait est
respond_to do |format|
format.html
format.json {render :json => {:medias => @medias.to_json, :total => 13000, :time => 0.0001 }}
end