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

Tri*_*ong 178 ruby-on-rails-3 rails-activerecord

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

"指定使用的源关联名称has_many :through => :queries.只有在无法从关联中推断出名称时才使用它.除非给出a,否则has_many :subscribers, :through => :subscriptions将查找:subscribers:subscriber打开."Subscription:source

von*_*rad 226

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

我不认为上面这段是多少比一个在文档更清晰,所以这里是一个例子.假设我们有三个模型Pet,DogDog::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
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们选择命名空间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
Run Code Online (Sandbox Code Playgroud)

有了:source,我们告诉Rails 寻找模型:breeds上的一个关联Dog(就像那个模型一样:dogs),然后使用它.

  • 在上面的例子中,如果`Dog`下的关联是`has_many:breed`而不是`:breeds`然后`:source`是`:breed` singular,来表示模型名称,而不是`:品种`表示表名?例如`has_many:dog_breeds,:through =>:dogs,:source =>:breed`(没有`s`后缀`:breed`)? (3认同)
  • 我认为你的意思是你的最后一类动物被称为班级宠物,我相信这只是一个错字. (2认同)
  • 我已经测试过这个。它是单数,`:source =&gt;` 中没有 `s` 后缀 (2认同)

Jer*_*ten 194

让我扩展一下这个例子:

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
Run Code Online (Sandbox Code Playgroud)

使用此代码,您可以执行类似Newsletter.find(id).users获取新闻稿订阅者列表的操作.但是,如果您想要更清楚并且能够键入Newsletter.find(id).subscribers,则必须将Newsletter类更改为:

class Newsletter
  has_many :subscriptions
  has_many :subscribers, :through => :subscriptions, :source => :user
end
Run Code Online (Sandbox Code Playgroud)

您正在将users关联重命名为subscribers.如果您不提供:source,则Rails将查找subscriber在Subscription类中调用的关联.您必须告诉它使用userSubscription类中的关联来生成订阅者列表.

  • 请注意,单数化模型名称应该用在`:source =>`中,而不是复数.所以,`:users`是错误的,`:user`是正确的 (2认同)

小智 9

最简单的答案:

表中间的关系名称是中间的.