208 votes

Besoin d’aide pour comprendre : option de has_one/has_many grâce à des Rails de source

S’il vous plaît m’aider à comprendre le option de association. L’explication de l’api de Rails est logique très peu pour moi

« Spécifie le nom d’association source utilisé par `` . Utilisez-le seulement si le nom ne peut être déduit de l’association.recherchera soit ou sur , sauf si un est donné. "

Merci.

276voto

vonconrad Points 14378

Parfois, vous voulez utiliser des noms différents pour les différentes associations. Si le nom que vous souhaitez utiliser pour une association sur le modèle n'est pas le même que l'association sur l' :through modèle, vous pouvez utiliser :source pour le spécifier.

Je ne pense pas que le paragraphe ci-dessus est beaucoup plus claire que celle dans les docs, donc voici un exemple. Imaginons que nous avons trois modèles, Pet, Dog et Dog::Breed.

class Pet < ActiveRecord::Base
  has_many :dogs
end

class Dog < ActiveRecord::Base
  belongs_to :pet
  has_many :breeds
end

class Dog::Breed < ActiveRecord::Base
  belongs_to :dog
end

Dans ce cas, nous avons choisi d'espace de noms de l' Dog::Breed, parce que nous voulons accéder Dog.find(123).breeds comme un joli et pratique de l'association.

Maintenant, si nous voulons maintenant créer un has_many :dog_breeds, :through => :dogs association sur Pet, nous avons soudain un problème. Rails de ne pas être en mesure de trouver un :dog_breeds association sur Dog, de sorte que les Rails ne peux pas le savoir qui Dog association que vous souhaitez utiliser. Entrez :source:

class Pet < ActiveRecord::Base
  has_many :dogs
  has_many :dog_breeds, :through => :dogs, :source => :breeds
end

Avec :source, nous racontons des Rails de regarder pour une association qui s'appelle :breeds sur le Dog modèle (c'est le modèle utilisé pour l' :dogs), et de l'utiliser.

223voto

Jeremy Ruten Points 59989

Permettez-moi de m'étendre sur cet exemple:

class User
  has_many :subscriptions
  has_many :newsletters, :through => :subscriptions
end

class Newsletter
  has_many :subscriptions
  has_many :users, :through => :subscriptions
end

class Subscription
  belongs_to :newsletter
  belongs_to :user
end

Avec ce code, vous pouvez faire quelque chose comme Newsletter.find(id).users pour obtenir une liste de la newsletter des abonnés. Mais si vous voulez être plus clair et d'être en mesure de taper Newsletter.find(id).subscribers au lieu de cela, vous devez modifier le Bulletin de la classe:

class Newsletter
  has_many :subscriptions
  has_many :subscribers, :through => :subscriptions, :source => :user
end

Vous êtes en renommant l' users association d' subscribers. Si vous ne fournissez pas l' :source, Rails de look pour une association qui s'appelle subscriber dans la classe d'Abonnement. Vous avez à le faire qu'à utiliser l' user association dans la classe d'Abonnement à la liste d'abonnés.

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