如何从 rails 中的两个来源建立一对多关系?
How to make one to many relationship from two sources in rails?
我有一个 Artist
模型,其中有很多 Reviews
。 Artists
也有很多 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 :gig
和 belongs_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 作为关联,但主要是如果您打算使用关联的方法(添加到集合、通过子项查找等)而不只是获取数据,这才有意义。
我有一个 Artist
模型,其中有很多 Reviews
。 Artists
也有很多 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 :gig
和 belongs_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 作为关联,但主要是如果您打算使用关联的方法(添加到集合、通过子项查找等)而不只是获取数据,这才有意义。