理解:Rails的has_one/has_many的源选项

请帮助我理解has_one/has_many :through关联的:source选项。Rails API的解释对我来说没什么意义。

"指定has_many使用的源关联名称:through => :查询> < /代码。仅当名称不能从 协会。has_many :subscribers, :through => :subscriptions将 在Subscription上查找:subscribers:subscriber, 除非给出:source。" < / p >

77435 次浏览

让我进一步解释一下这个例子:

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关联来创建订阅者列表。

有时,您希望为不同的关联使用不同的名称。如果你想用于模型上的关联的名称与:through模型上的关联不相同,你可以使用:source来指定它。

我不认为上面的段落比文档中的更清晰,所以这里有一个例子。假设我们有三个模型,PetDogDog::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作为一个良好和方便的关联。

现在,如果我们现在想在Pet上创建一个has_many :dog_breeds, :through => :dogs关联,我们突然有一个问题。Rails无法在Dog上找到:dog_breeds关联,因此Rails不可能知道你想要使用的哪一个 Dog关联。输入:source:

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

对于:source,我们告诉Rails 在__ABC2模型上寻找一个名为:breeds的关联(因为这是用于:dogs的模型),并使用它。

最简单的答案:

是中间表中关系的名称。