2011-08-30 12 views
6

Sé cómo desactivar el elemento raíz globalmente, a la Rails 3.1 include_root_in_json o usando ActiveRecord::Base.include_root_in_json = false, pero solo quiero hacer esto para unas pocas solicitudes JSON (no globalmente).Rieles: ¿Deshabilita la raíz en JSON solo para acciones específicas del controlador?

Hasta ahora, he estado haciendo de esta manera:

@donuts = Donut.where(:jelly => true) 
@coffees = Coffee.all 
@breakfast_sandwiches = Sandwich.where(:breakfast => true) 

dunkin_donuts_order = {} 
dunkin_donuts_order[:donuts] = @donuts 
dunkin_donuts_order[:libations] = @coffees 
dunkin_donuts_order[:non_donut_food] = @breakfast_sandwiches 

Donut.include_root_in_json = false 
Coffee.include_root_in_json = false 

render :json => dunkin_donuts_order 

Donut.include_root_in_json = true 
Coffee.include_root_in_json = true 

Hay alrededor de 5 casos en los que tengo que hacer esto, a veces con más de un modelo, y no se siente limpio en todas. Había intentado poner esto en around_filter s, pero las excepciones estaban rompiendo el flujo, y que se estaba poniendo peludo también.

¡Debe haber una manera mejor!

+0

Esto no responde directamente a su pregunta, pero responde la que busqué aquí: PUEDE suprimir la raíz en llamadas individuales a 'to_json', p. Ej. 'Donut.to_json (root: falso)' – Lambart

Respuesta

2

La respuesta es, lamentablemente, sí y no.

Sí, lo que has hecho anteriormente puede decirse que se puede hacer mejor. No, Rails no le permitirá agregar la raíz por acción. El renderizado JSON simplemente no fue construido con ese tipo de flexibilidad en mente.

Dicho esto, aquí es lo que haría:

  1. Conjunto include_root_in_json-false para aquellos modelos que tienen raíz en función de la acción (como Donut y Coffee arriba).
  2. Anule as_json para permitir una mayor flexibilidad. He aquí un ejemplo:

    # in model.rb 
    def as_json(options = nil) 
        hash = serializable_hash(options) 
        if options && options[:root] 
         hash = { options[:root] => hash } 
        else 
         hash = hash 
        end 
    end 
    

    En este ejemplo se hará de modo que se puede pasar opcionalmente una raíz pero pasará al no tener raíz. Alternativamente, podrías escribirlo de otra manera.

  3. Dado que omitió as_json, tendrá que modificar sus llamadas de representación de forma adecuada. Entonces, para Donut, harías render :json => @donut.to_json.

Hope this helps!

+0

Gracias. Dejé de dispararme en el pie y cambié a [RABL] (https://github.com/nesquena/rabl) y nunca miré hacia atrás. ¡Mucho mejor! – neezer

+0

Buena respuesta. pero no tienes que llamar a as_json(). to_json porque to_json llama automáticamente a tu as_json override. –

+0

Gracias, @NadaAldahleh. He aclarado ese poco en mi respuesta. –

1

Puede establecer include_root_in_json por ejemplo modelo , y no va a afectar a la de la clase (ver class_attribute en la API de rieles para una descripción de este comportamiento). De modo que puede establecer un valor predeterminado razonable en el nivel de clase, luego establecer un valor diferente en cada instancia en los controladores relevantes.

Ejemplo:

@donuts = Donut.where(:jelly => true).each {|d| d.include_root_in_json = false } 

Por conveniencia, se puede crear un método de utilidad que acepta un conjunto de instancias de modelo y establece el valor en todos ellos.

Cuestiones relacionadas