2010-09-15 8 views
16

Estoy usando respond_with y todo está conectado correctamente para obtener datos correctamente. Quiero personalizar los formatos devueltos json, xml y foobar de una manera SECA, pero no puedo encontrar la manera de hacerlo usando los :only y :include limitados. Estos son excelentes cuando los datos son simples, pero con hallazgos complejos, no alcanzan lo que deseo.Cómo personalizar la respuesta to_json en Rails 3

Digamos que tengo un puesto que has_many imágenes

def show 
    @post = Post.find params[:id] 
    respond_with(@post) 
end 

quiero incluir las imágenes con la respuesta que yo pudiera hacer esto:

def show 
    @post = Post.find params[:id] 
    respond_with(@post, :include => :images) 
end 

pero realmente no quieren enviar a la todo el objeto de imagen, solo la url. Además de esto, realmente quiero ser capaz de 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 SECO. En proyectos de rieles más antiguos, he utilizado constructores de XML para personalizar el resultado, pero replicarlo en json, xml, html lo que no parece correcto. Tengo que imaginarme que los gurús de los rieles ponen algo en Rails 3 que no me estoy dando cuenta de este tipo de comportamiento. Ideas?

Respuesta

7

No son los rieles de 3 vías incorporado, pero he encontrado un gran tesoro que se mantiene de forma activa en los carriles 3: acts_as_api

+1

Este enlace es un 404. – lashleigh

+2

https://github.com/fabrik42/acts_as_api – coneybeare

21

Puede anular as_json en su modelo. Algo así 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 los rieles se encarga del resto cuando se utiliza respond_with. no del todo seguro de lo options consigue el sistema para, pero probablemente las opciones que dan a respond_with (:include, :only y así sucesivamente)

+2

Quiere cambiar as_json, as_xml, as_foobar todo en un solo lugar. – scragz

+0

Sí, esto no es realmente DRY – coneybeare

+0

'include' no usa' as_json', esto no ayuda. – Meekohi

8

Probablemente demasiado tarde, pero he encontrado una solución más SECO cavar a través de la documentación de los carriles. Esto funciona en mis pruebas breves, pero puede ser necesario ajustar algunos parámetros:

# 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 que están permitidos para su API pública, y no se puede exponer accidentalmente el objeto entero. Todavía puede exponer campos específicos manualmente, pero de forma predeterminada su objeto es seguro para .to_json, .to_xml, etc.

+0

En realidad, esto debería ser el predeterminado cuando: solo no se especifica, de lo contrario cambia la intención de usar: solo. Oh, bueno, todavía mi punto es el mismo. – Nerdmaster

+0

Reemplazar serializable_hash funcionó mejor para agregar algunos métodos como atributos en Rails 3.2.8, ¡gracias! – Docunext

+0

Esta es la respuesta correcta. También funciona en Rails 4. – Meekohi

Cuestiones relacionadas