ruby-on-rails - only - ruby and rails documentation
as_json no llama as_json a las asociaciones (6)
Como se reconoció anteriormente, este es un problema con la base de Rails. El parche de los rieles github.com/rails/rails/pull/2200 todavía no se aplica y parece al menos un poco controvertido, por lo que dudo en aplicarlo localmente. Incluso si se aplica como un parche de mono, podría complicar futuras actualizaciones de rieles.
Todavía estoy considerando RABL sugerido anteriormente, parece útil. Por el momento, prefiero no agregar otro lenguaje de plantillas de visualización en mi aplicación. Mis necesidades actuales son muy pequeñas.
Así que aquí hay una solución que no requiere un parche y funciona para la mayoría de los casos simples. Esto funciona donde el método as_json
la asociación que te gustaría llamar se parece a
def as_json(options={})
super( <... custom options ...> )
end
En mi caso, tengo el modelo de Schedule
que tiene muchos Events
class Event < ActiveRecord::Base
# define json options as constant, or you could return them from a method
EVENT_JSON_OPTS = { :include => { :locations => { :only => [:id], :methods => [:name] } } }
def as_json(options={})
super(EVENT_JSON_OPTS)
end
end
class Schedule < ActiveRecord::Base
has_many :events
def as_json(options={})
super(:include => { :events => { Event::EVENT_JSON_OPTS } })
end
end
Si siguió la directriz de que cada vez que :include
una asociación en sus métodos as_json()
, defina las opciones que necesita como una constante en el modelo que se va a referenciar, esto funcionaría para niveles arbitrarios de asociaciones. NOTA : solo necesitaba el primer nivel de asociación personalizado en el ejemplo anterior.
Tengo un modelo con datos que nunca deberían incluirse cuando se representa como json. Así que implementé el método de clase ''as_json'' para comportarme adecuadamente. El problema es que cuando otros modelos con asociaciones con este modelo hacen json, mi costumbre as_json no se está llamando.
class Owner < ActiveRecord::Base
has_one :dog
def as_json(options={})
puts "Owner::as_json"
super(options)
end
end
class Dog < ActiveRecord::Base
belongs_to :owner
def as_json(options={})
puts "Dog::as_json"
options[:except] = :secret
super(options)
end
end
Entorno de desarrollo de carga (Rails 3.0.3)
ruby-1.9.2-p136: 001> d = Dog.first
=>#<Dog id: 1, owner_id: 1, name: "Scooby", secret: "I enjoy crapping everwhere"
>
ruby-1.9.2-p136: 002> d.as_json
Perro :: as_json
=> {"perro" => {"id" => 1, "nombre" => "Scooby", "owner_id" => 1}}
ruby-1.9.2-p136: 004> d.owner.as_json (: include =>: perro)
Propietario :: as_json
=> {"owner" => {"id" => 1, "name" => "Shaggy",: dog => {"id" => 1, "nombre" => "Scooby", "owner_id" = > 1, "secreto" => "Me gusta crapping everwhere"}}}
Gracias por la ayuda
Descubrí que serializable_hash funciona como esperarías que as_json funcione, y siempre se llama:
def serializable_hash(options = {})
result = super(options)
result[:url] = "http://.."
result
end
Este es un error conocido en Rails. (El problema se marcó como cerrado debido a la migración a problemas de Github del rastreador de errores anterior, pero sigue siendo un problema a partir de Rails 3.1).
Esto fue reportado como un error: http://ternarylabs.com/2010/09/07/migrating-to-rails-3-0-gotchas-as_json-bug/
Me encontré con el mismo problema. Yo quería que esto funcionara
render :json => @favorites.as_json(:include => :location)
Pero no fue así, terminé agregando un index.json.erb con lo siguiente:
<% favs = @favorites.as_json.each do |fav| %>
<% fav["location"] = Location.find(fav["location_id"]).as_json %>
<% end %>
<%= favs.to_json.html_safe %>
No es una solución, solo una solución. Me imagino que hiciste lo mismo.
Update @John señaló que este es un error conocido en Rails. Parece que hay un parche para reparar: en github.com/rails/rails/pull/2200 . Sin embargo, puedes probar RABL, porque es dulce.
Siempre me he sentido frustrado al pasar un conjunto complejo de opciones para crear las vistas JSON que quiero. Tu problema, que experimenté con Mongoid en Rails 3.0.9, me impulsó a escribir plantillas JSON. Pero en realidad, si se trata de relaciones o propiedades api personalizadas, resulta que las plantillas son mucho mejores.
Además, lidiar con diferentes productos me parece la capa Ver, así que RABL usar RABL , el lenguaje de plantillas API. Hace que sea muy fácil construir JSON válido e incluir cualquier asociación o campo.
No es una solución al problema, sino una mejor solución para el caso de uso.