ruby on rails - Cómo personalizar la respuesta de to_json en Rails 3
render json rails 5 (3)
No son los rieles 3 integrados, pero encontré una gran joya que se mantiene activamente en los rieles 3: acts_as_api
Estoy usando respond_with
y todo está conectado correctamente para obtener los datos correctamente. Quiero personalizar los formatos json
, xml
y foobar
devueltos en modo DRY, pero no puedo averiguar cómo hacerlo utilizando el limitado :only
y :include
. Estos son excelentes cuando los datos son simples, pero con hallazgos complejos, no llegan a lo que quiero.
Digamos que tengo una publicación que tiene has_many
imágenes
def show
@post = Post.find params[:id]
respond_with(@post)
end
Quiero incluir las imágenes con la respuesta para poder hacer esto:
def show
@post = Post.find params[:id]
respond_with(@post, :include => :images)
end
pero realmente no quiero enviar todo el objeto de la imagen, solo la url. Además de esto, realmente quiero poder hacer algo como esto también (pseudocódigo):
def show
@post = Post.find params[:id]
respond_with(@post, :include => { :foo => @posts.each.really_cool_method } )
end
def index
@post = Post.find params[:id]
respond_with(@post, :include => { :foo => @post.really_cool_method } )
end
... pero todo de una manera seca. En proyectos de rieles anteriores, he usado constructores XML para personalizar el resultado, pero replicándolo en json, xml, html, lo que no parezca correcto. Tengo que imaginar que los gurús de Rails ponen algo en Rails 3 que no me estoy dando cuenta de este tipo de comportamiento. Ideas?
Probablemente demasiado tarde, pero encontré una solución más SECA cavando en los documentos de los rieles. Esto funciona en mis pruebas breves, pero puede necesitar algunos ajustes:
# This method overrides the default by forcing an :only option to be limited to entries in our
# PUBLIC_FIELDS list
def serializable_hash(options = nil)
options ||= {}
options[:only] ||= []
options[:only] += PUBLIC_FIELDS
options[:only].uniq!
super(options)
end
Básicamente, esto le permite tener una lista de campos permitidos para su API pública y no puede exponer accidentalmente todo el objeto. Aún puede exponer campos específicos manualmente, pero por defecto su objeto es seguro para .to_json, .to_xml, etc.
Puede anular as_json
en su modelo. Algo como:
class Post < ActiveRecord::Base
def as_json(options = {})
{
attribute: self.attribute, # and so on for all you want to include
images: self.images, # then do the same `as_json` method for Image
foo: self.really_cool_method
}
end
end
Y Rails se encarga del resto cuando usa respond_with
. no del todo seguro de qué options
se configuran, pero probablemente las opciones que le da a respond_with
( :include
respond_with
:only
y así sucesivamente)