我找到了一大堆关于 "source: "的文章、stackoverflow的答案和rails文档,但没有一篇文章以我能理解的方式解释这种关联方式。如果可能的话,我需要对这种关联方式进行最简化的解释。
我的例子是这样的。
相册:
has_many :reviews, :dependent => :destroy
has_many :reviewers, through: :reviews, source: :user
belongs_to :user
评论:
belongs_to :album, optional: true
belongs_to :user
用户:
has_many :reviews
has_many :reviewed_albums, through: :reviews, source: :album
has_many :albums
代码的其余部分没有提到 "评论者 "或 "reviewed_albums",所以这是我最不理解的部分。
这些名字是否完全不相关?
TL;DR
source
是代表这个关联所指向的表,因为我们给它一个不同的名字,而不仅仅是 .users
因为我们已经有了 belongs_to :user
协会。
漫长的解释
我觉得用这个小图最简单,它基本上就是你上面发的模型的数据库模式。
我们有相册,是属于用户的,也就是说用户基本上就是创建一个相册的人。我们还有评论,评论是属于ablums的,也就是说一张专辑可以被评论。而评论是由用户做出的,所以这就是为什么评论属于用户。
现在,rails中的关联是一种创建方法的方式,可以在数据库记录上调用这些方法来找到它的关联记录。
比如说我们可以从一个专辑中得到一个用户或者一个用户所做的所有评论。
album = Album.find(1)
album.user # => returns the creator of the album
user = User.first
user.reviews # => returns all the reviews a user made
现在这些模型之间的联系甚至比上面提到的更多。
我们先来看看专辑。
# album.rb
has_many :reviews, :dependent => :destroy
belongs_to :user
has_many :reviewers, through: :reviews, source: :user
一张专辑属于一个用户,他创建了它。它有很多评论。而且,如果我们沿着从相册到评论的路线,再进一步到用户表,我们看到,我们也可以访问提供评论的用户。
album.reviews.users
意思是:给我所有为这张专辑留下评论的用户。现在,这行代码将无法工作--因为 album.reviews
返回一个数组(准确的说是一个ActiveRecord::Relation对象),我们不能只调用 .users
但我们可以有另一个协会
has_many :reviewers, through: :reviews, source: :user
而在这里,他们称之为 reviewers
以免与方法关联混淆。.user
指的是创建者。通常情况下,Rails会从关联的名称中引用数据库表的名称。由于我们在这里给出了一个不同的名称,我们必须明确给出我们要引用的DB表的名称,那就是user表。
所以这就是这一行的内容--我们创建了另一个关联,我们不希望专辑和用户之间有直接的联系(见图),我们希望有在这个专辑上留下评论的用户,所以我们走了 through
然后我们要给评论表起个名字(source
)的表,这样Rails就知道该在哪个表中查找。
而这也终于让我们可以写出这样的代码。
album = Album.first
album.user # => creator of the album
album.reviewers # => all users that have left a review for this album
希望能帮到你!如果你有更多的问题,请告诉我,也许你可以在评论中解释一下用户模型中与源代码的其他关联。