请解释has_many,通过:来源:Rails协会

Please explain the has_many, through: source: Rails Association

我找到了很多关于 'source:' 的文章、Whosebug 答案和 rails 文档,但其中 none 以我能理解的方式解释了这种关联。如果可能的话,我需要这种关联方式的最简单的解释。

我的例子是这样的:

专辑:

    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

其余代码没有提到"reviewers"或"reviewed_albums",所以这是我最不了解的部分。

这些名字完全不相关吗?

TL;DR

source 代表这个关联所指的 table,因为我们给它取了一个不同于 .users 的名称,因为我们已经有了 belongs_to :user协会。

详细解释

我认为这张小图片最简单,它基本上是您上面发布的模型的数据库模式。

我们有属于用户的相册,这意味着用户基本上就是创建相册的人。我们也有评论,它们属于专辑,这意味着专辑可以被评论。评论是由用户做出的,因此评论属于用户。

现在 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

一个相册属于创建它的一个用户。它有很多评论。而且,如果我们沿着从相册到评论的路线,然后进一步到用户 table,我们会发现我们还可以访问给出评论的用户。 所以我们想做一些像

album.reviews.users

含义:给我所有对这张专辑发表评论的用户。现在这行代码行不通了——因为 album.reviews returns 一个数组(确切地说是一个 ActiveRecord::Relation 对象)我们不能只调用 .users 。 但是我们可以有另一个关联

has_many :reviewers, through: :reviews, source: :user

这里我们称它为 reviewers,以免与指代创作者的 method/association .user 混淆。通常,Rails 会引用关联名称中的数据库 table 名称。由于我们在这里给出了不同的名称,因此我们必须明确给出我们所指的数据库 table 的名称,即用户 table.

所以这就是这条线的意思 - 我们创建了另一个关联,我们不想要相册和用户之间的直线(见图片),我们想要在这个相册上留下评论的用户,所以我们转到 through 评论 table 然后我们必须给出 table 的名称 (source) 所以 Rails 知道 table看

这最终将允许我们编写如下代码:

album = Album.first
album.user # => creator of the album
album.reviewers # => all users that have left a review for this album

希望对您有所帮助!如果您还有其他问题,请告诉我。 也许您可以在评论中解释用户模型中与来源的其他关联。