S'il vous plaît aidez-moi à comprendre le :source
option de has_one/has_many :through
_ association. L’explication de l’API Rails) n’a guère de sens pour moi.
"Spécifie le nom d'association source utilisé par
has_many
:through => :queries
. Utilisez-le uniquement si le nom ne peut pas être déduit de l'association.has_many :subscribers, :through => :subscriptions
va rechercher soit:subscribers
ou:subscriber
surSubscription
, sauf si un:source
est donnée. "
Parfois, vous souhaitez utiliser des noms différents pour différentes associations. Si le nom que vous souhaitez utiliser pour une association sur le modèle n'est pas identique à l'assocation sur le modèle :through
, Vous pouvez utiliser :source
Pour le spécifier.
Je ne pense pas que le paragraphe ci-dessus soit beaucoup plus clair que celui de la documentation, alors voici un exemple. Supposons 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 l’espace de noms Dog::Breed
, Car nous voulons accéder à Dog.find(123).breeds
en tant qu’association pratique et agréable.
Maintenant, si nous voulons maintenant créer une association has_many :dog_breeds, :through => :dogs
Sur Pet
, nous avons soudainement un problème. Rails ne pourra pas trouver d'association :dog_breeds
Sur Dog
, donc Rails ne peut pas savoir quelle association Dog
vous souhaitez utiliser. Entrez :source
:
class Pet < ActiveRecord::Base
has_many :dogs
has_many :dog_breeds, :through => :dogs, :source => :breeds
end
Avec :source
, Nous disons Rails à recherchez une association appelée :breeds
Sur le modèle Dog
.) (comme c'est le modèle utilisé pour :dogs
), et l'utiliser.
Permettez-moi de développer 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 des abonnés à la newsletter. Mais si vous voulez être plus clair et pouvoir taper Newsletter.find(id).subscribers
à la place, vous devez changer la classe Newsletter en ceci:
class Newsletter
has_many :subscriptions
has_many :subscribers, :through => :subscriptions, :source => :user
end
Vous renommez l'association users
en subscribers
. Si vous ne fournissez pas le :source
, Rails recherchera une association appelée subscriber
dans la classe Subscription. Vous devez lui indiquer d'utiliser le user
association dans la classe Subscription pour créer la liste des abonnés.
Réponse la plus simple:
Est le nom de la relation dans la table au milieu.