ruby-on-rails - respond - serializer rails
Agregar atributo virtual a la salida json (7)
Como mencionó anteriormente :methods
le permitirán devolver el método / función de un modelo específico como un atributo json, en caso de que tenga assosiations complejas esto hará el truco ya que agregará funciones al modelo existente / assosiations: D funcionará como un amuleto si no quieres redefinir as_json
Verifique este código, y observe cómo estoy usando :methods
, así como :include
[N + Query ni siquiera es una opción;)]
render json: @YOUR_MODEL.to_json(:methods => [:method_1, :method_2], :include => [:company, :surveys, :customer => {:include => [:user]}])
Sobrescribir la función as_json
será mucho más difícil en este escenario (especialmente porque tiene que agregar :include
assosiations manualmente: / def as_json(options = { }) end
Digamos que tengo una aplicación que maneja una lista TODO. La lista tiene elementos terminados y sin terminar. Ahora quiero agregar dos atributos virtuales al objeto de la lista; el recuento de elementos terminados y no finalizados en la lista. También necesito que estos se muestren en la salida json.
Tengo dos métodos en mi modelo que obtiene los elementos sin terminar / terminados:
def unfinished_items
self.items.where("status = ?", false)
end
def finished_items
self.items.where("status = ?", true)
end
Entonces, ¿cómo puedo obtener el recuento de estos dos métodos en mi salida json?
Estoy usando Rails 3.1
Con Rails 4, puede hacer lo siguiente:
render json: @my_object.to_json(:methods => [:finished_items, :unfinished_items])
Espero que esto ayude a alguien que está en la última / última versión
Esto servirá, sin tener que hacer algunas suposiciones desagradables. Si tiene una List
modelo, por ejemplo, puede poner esto en su controlador:
render json: list.attributes.merge({
finished_items: list.finished_items,
unfinished_items: list.unfinished_items
})
La serialización de objetos en Rails tiene dos pasos:
- Primero,
as_json
es llamado para convertir el objeto a Hash simplificado. - Luego,
to_json
seto_json
en el valor de retornoas_json
para obtener la cadena JSON final.
Por lo general, quiere irse solo to_json
, así que todo lo que necesita hacer es agregar su propia implementación as_json
de la siguiente manera:
def as_json(options = { })
# just in case someone says as_json(nil) and bypasses
# our default...
super((options || { }).merge({
:methods => [:finished_items, :unfinished_items]
}))
end
También podrías hacerlo así:
def as_json(options = { })
h = super(options)
h[:finished] = finished_items
h[:unfinished] = unfinished_items
h
end
si desea utilizar diferentes nombres para los valores respaldados por método.
Si le importan XML y JSON, eche un vistazo a serializable_hash
.
Otra forma de hacerlo es agregar esto a su modelo:
def attributes
super.merge({''unfinished'' => unfinished_items, ''finished'' => finished_items})
end
Esto también funcionaría automáticamente para la serialización xml. serializable_hash embargo, tenga en cuenta que es posible que desee utilizar cadenas para las claves, ya que el método no puede tratar con símbolos al ordenar las claves en rieles 3. Pero no es ordenados en rieles 4, por lo que ya no debería haber un problema.
Solo pensé en proporcionar esta respuesta para cualquier persona como yo, que intentaba integrar esto en un bloque as_json existente:
def as_json(options={})
super(:only => [:id, :longitude, :latitude],
:include => {
:users => {:only => [:id]}
}
).merge({:premium => premium?})
Simplemente .merge({})
al final de tu super()
simplemente cierre todos sus datos en un hash , como
render json: {items: items, finished: finished, unfinished: unfinished}