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类中寻找一个关联。您必须告诉它使用user
Subscription类中的关联来创建订户列表。
:source =>
,而不是复数形式。所以,这:users
是错误的,:user
是正确的