【发布时间】:2020-08-26 01:29:34
【问题描述】:
我正在寻找一个 DRY 解决方案来解决在 Rails 中组合两个或多个包含不同连接和分组的范围的问题。我有一个 ::with_authors 范围的 cmets 模型(以防止在引用作者姓名时出现 N+1),如下所示:
# comment.rb
scope :with_authors, -> do
select("comments.*, users.username AS author_name")
.joins(:author)
end
我对允许 cmets 和其他模型从用户那里获得投票的多态关联有一个“可投票”的担忧。这包括一个::with_votes 范围,如下所示:
# votable.rb
scope :with_votes, -> do
select( "#{self.table_name}.*, COALESCE(SUM(votes.value), 0) AS vote_sum" )
.left_joins(:votes)
.group("#{self.table_name}.id")
end
两个范围都需要显示带有作者姓名和收到的投票数的 cmets 列表。但是将两者结合起来,post.cmets.with_authors.with_votes,会导致熟悉的错误:
> PG::GroupingError: ERROR: column "users.username" must appear in the
> GROUP BY clause or be used in an aggregate function
我意识到我可以编写一个单独的范围来执行连接并相应地更改分组,但这不能转移到支持投票的其他模型,并且违反了每个方法或范围应该做一件事的原则。我也尝试使用合并 - post.cmets.with_authors.merge( post.cmets.with_votes ) - 但这给出了同样的错误。有没有办法编写一个或两个范围,以便它们一起工作,但它们也可以单独使用,同时确保 ::with_votes 适用于使用可投票关联的其他模型?非常感谢期待!
【问题讨论】:
标签: ruby-on-rails ruby postgresql group-by