with rails from before_action ruby-on-rails json api

ruby on rails - rails - render: json no acepta opciones



rails render with params (5)

Me encantaría usar render :json pero parece que no es tan flexible. ¿Cuál es la forma correcta de hacer esto?

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


Gestionar hashes complejos en sus controladores se pone feo rápidamente.

Con Rails 3, puede usar ActiveModel :: Serializer. Ver http://api.rubyonrails.org/classes/ActiveModel/Serialization.html

Si está haciendo algo que no sea trivial, consulte https://github.com/rails-api/active_model_serializers . Recomiendo crear clases de serializador por separado para evitar abarrotar sus modelos y facilitar las pruebas.

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


He hecho algo similar con render :json . Esto es lo que funcionó para mí:

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


Supongo que este artículo puede ser útil para usted: ¿ Rails to_json o as_json? por Jonathan Julian.

La idea principal es que debes evitar usar to_json en los controladores. Es mucho más flexible definir el método as_json en su modelo.

Por ejemplo:

En tu modelo de cosa

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

Y luego puedes escribir solo en tu controlador

render :json => @things


en el caso de array lo que hice es

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


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