如何从 rails 中的两个来源建立一对多关系?

How to make one to many relationship from two sources in rails?

我有一个 Artist 模型,其中有很多 ReviewsArtists 也有很多 Gigs,而 Gigs 又有很多 reviews。评论可以直接来自 Artist,也可以来自 Artist 所做的 Gigs。我希望能够做这样的事情:

Artist.first.reviews
# Should return reviews directly from the artist as well as from artist.gigs

我该如何建模?我应该在我的模型中定义一个像 all_reviews 这样的新方法来获取和合并 reviews 还是有任何直接的关联方式?

我肯定会选择 all_reviews 方法。话虽这么说,但如何优化它很有趣。

您使用的是多态字段还是您的 Review 模型 belongs_to :gigbelongs_to :artist

如果是第二种情况,你可以在你的 Review 模型中做这样的事情:

def all_reviews
  Review.where(['reviews.gig_id IN ? OR reviews.artist_id = ?', gigs, id])
end

这应该没问题,但是如果您使用的是多态字段,我们称它为 reviewer,您可以这样做:

def all_reviews
  Review.where([
    '(reviews.reviewer_type = ? AND reviews.reviwer_id IN ?) OR (reviews.reviewer_type = ? AND reviews.review_id = ?)',
    'Gig', gigs, 'Artist', id
  ])
end

两者都应该没问题。请注意我没有手动测试代码,所以可能会有错误

多态关联帮你解决这个问题。参见 the guide

在您的情况下,代码如下所示:

Class Artist
  has_many :reviews, as: reviewable
  has_many :gigs

  def all_reviews
    reviews + gigs.reviews
  end
end

Class Gig
  has_many :reviews, as: reviewable
  belongs_to :artist
end

Class Reviewable
  belongs_to :reviewable, polymorphic: true
end

您也可以将方法 all_reviews 作为关联,但主要是如果您打算使用关联的方法(添加到集合、通过子项查找等)而不只是获取数据,这才有意义。