Answers:
有时,您想对不同的关联使用不同的名称。如果要用于模型上的关联的名称与模型上的关联不同,则:through可以使用:source它来指定它。
我认为上面的段落没有比文档中的段落更清楚,因此这里是一个示例。假设我们有Pet,Dog和三个模型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
在这种情况下,我们选择为命名空间Dog::Breed,因为我们想Dog.find(123).breeds作为一个很好且方便的关联进行访问。
现在,如果现在要在上创建has_many :dog_breeds, :through => :dogs关联Pet,则突然有问题。Rails无法在上找到:dog_breeds关联Dog,因此Rails可能无法知道您要使用哪个 Dog关联。输入:source:
class Pet < ActiveRecord::Base
has_many :dogs
has_many :dog_breeds, :through => :dogs, :source => :breeds
end
使用:source,我们告诉Rails 查找:breeds在Dog模型上调用的关联(因为正是该模型用于:dogs),然后使用它。
Dog是has_many :breed而不是:breeds然后:source是:breed单数,以代表模型名称,而不是:breeds代表表名称?例如has_many :dog_breeds, :through => :dogs, :source => :breed(不带s后缀:breed)?
s后缀:source =>
让我继续这个例子:
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
使用此代码,您可以执行类似Newsletter.find(id).users获取新闻通讯订阅者列表的操作。但是,如果您想更清晰并能够键入Newsletter.find(id).subscribers,则必须将Newsletter类更改为:
class Newsletter
has_many :subscriptions
has_many :subscribers, :through => :subscriptions, :source => :user
end
您正在将users关联重命名为subscribers。如果您不提供:source,Rails将subscriber在Subscription类中寻找一个关联。您必须告诉它使用userSubscription类中的关联来创建订户列表。
:source =>,而不是复数形式。所以,这:users是错误的,:user是正确的