35 votes

as_json n'appelle pas as_json sur les associations

J'ai un modèle avec des données qui ne doivent jamais être inclus lorsqu'il est rendu sous forme de json. J'ai donc implémenté la classe' as_json méthode pour se comporter de manière appropriée. Le problème, c'est quand d'autres modèles avec des associations avec ce modèle de rendu json, ma coutume as_json n'est pas appelée.

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

Le chargement de l'environnement de développement (Rails 3.0.3)
ruby 1.9.2-p136 :001 > d = Chien.première
=> #<Dog id: 1, owner_id: 1, name: "Scooby", secret: "I enjoy crapping everwhere">
ruby 1.9.2-p136 :002 > d.as_json
Chien::as_json
=> {"chien"=>{"id"=>1, "nom"=>"Scooby", "owner_id"=>1}}
ruby 1.9.2-p136 :004 > d.propriétaire.as_json(:include => :chien)
Propriétaire::as_json
=> {"propriétaire"=>{"id"=>1, "nom"=>"Shaggy", :chien=>{"id"=>1, "nom"=>"Scooby", "owner_id"=>1, "secret"=>"j'aime chier partout"}}}

Merci pour l'aide

21voto

John Points 9709

Il s'agit d'un bug connu dans Rails. (Le problème est marqué comme fermé en raison de la migration vers des problèmes Github à partir du suivi des bogues précédent, mais c'est toujours un problème depuis Rails 3.1.)

9voto

shakerlxxv Points 139

Ainsi que l'a indiqué ci-dessus, c'est un problème avec les Rails de base. Les rails patch ici n'est pas encore appliquée et semble au moins de controverse, donc j'hésite à appliquer localement. Même s'il est appliqué comme un singe patch il pourrait compliquer les futures rails de mises à niveau.

Je suis toujours compte tenu de RABL suggéré ci-dessus, il paraît utile. Pour le moment, je préfère ne pas en ajouter un autre point de vue de template langue dans mon application. Mes besoins sont très petites.

Voici donc une solution qui ne nécessite pas de patch et de travail dans la plupart des cas. Cela fonctionne lorsque l'association de l' as_json méthode que vous aimeriez avoir appelé ressemble

def as_json(options={})
  super( <... custom options ...> )
end

Dans mon cas, j'ai Schedule modèle qui a beaucoup d' 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 vous avez suivi la ligne directrice qu'à chaque fois que vous :include une association dans votre as_json() méthodes, vous définissez les options que vous avez besoin comme une constante dans le modèle de référence, ce serait de travailler pour des niveaux arbitraires des associations. REMARQUE je n'avais besoin que le premier niveau de l'association personnalisé dans l'exemple ci-dessus.

2voto

Dan Hixon Points 188

J'ai rencontré le même problème. Je voulais que cela fonctionne:

 render :json => @favorites.as_json(:include => :location)
 

Mais ce n'est pas le cas, j'ai donc fini par ajouter un index.json.erb avec ce qui suit:

 <% favs = @favorites.as_json.each do |fav| %>
    <% fav["location"] = Location.find(fav["location_id"]).as_json %>
<% end %>
<%= favs.to_json.html_safe %>
 

Pas une solution - juste une solution de contournement. J'imagine que tu as fait la même chose.

1voto

arbales Points 2108

Mise à jour @John a souligné c'est un bogue connu dans les Rails. Un patch pour corriger cela semble être: à https://github.com/rails/rails/pull/2200. Néanmoins, vous pouvez essayer de RABL, en raison de son doux.

J'ai toujours été frustré par le passage d'un ensemble complexe d'options pour créer le JSON points de vue que je veux. Votre problème, que j'ai connu avec Mongoid dans les Rails 3.0.9, m'a incité à écrire des modèles JSON. Mais en fait, si vous avez affaire à des relations personnalisées ou api propriétés, il s'avère que les modèles sont de façon plus agréable.

Par ailleurs, traiter avec les différentes sorties semble que la couche de la Vue pour moi, donc je me suis installé sur l'utilisation de RABL, l'API de création de modèles de langue. Il rend super facile à construire JSON valide, et comprennent toutes les associations ou dans les champs.

Pas une solution au problème, mais une meilleure solution pour le cas d'utilisation.

0voto

Jonathan Julian Points 9172

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X