【问题标题】:Order data by association-related properties in Rails?在 Rails 中按关联相关属性排序数据?
【发布时间】:2021-07-03 05:27:35
【问题描述】:
我有一个Post 模型和一个Review 模型,它们之间是一对多的关系。我正在尝试编写控制器代码来对帖子进行排序。我希望用户能够对帖子进行排序的一种方法是通过他们的汇总评分,目前是通过属于该帖子的所有review.ratings 的简单平均值计算的。对于更简单的排序,我可以做类似Post.order(id: :asc) 的操作,但是因为每个帖子的平均评分在数据库中不是一个明确的属性,所以同样的方法不起作用。
我现在想知道尝试使用我没有经验的 SQL 是否是一个好主意,我是否应该在 Posts 模型中创建一个方法来返回所有帖子。显然我写的代码不如框架写的好,所以毫无疑问我的方法效率会低很多。
假设我以后还想添加更多排序方法,这里最好的方法是什么?仅此一次的拼接解决方案行不通。
【问题讨论】:
标签:
sql
ruby-on-rails
postgresql
【解决方案1】:
可以创建一个 SQL 查询来动态汇总平均评论分数然后进行排序,但通常这不会很高效。当数据库可以使用索引时,对记录进行排序是最快的。如果您想对帖子进行分页,计算顺序必须计算每个条目的值,以便确定要显示的元素 - 因此,如果您显示 10,000 条记录中的 10 条记录,那是 很多浪费处理。
相反,我建议在您的Post 记录中添加一个字段——比如:review_average,并为其指定一个索引。在你的帖子类中添加一个计算评论分数的方法:
class Post < ApplicationRecord
has_many :reviews, inverse_of: :post
def update_review_average
update review_average: reviews.average(:rating)
end
end
class Review < ApplicationRecord
belongs_to :post, inverse_of: :reviews
after_create :update_post
after_destroy :update_post
private
def update_post
post.update_review_average
end
end
这样,您可以使用.order(review_average: :desc) 进行排序,而且速度会非常快。