我有2个班级:
class Solution
has_many :solution_votes
class SolutionVote
belongs_to :solution
我的观点中有类似的内容:
Proposed Solution A - 2 votes up - 5 votes down
Proposed Solution B - 1 vote up - 0 votes down
Proposed Solution C - 0 votes up - 0 votes down
Proposed Solution D - 7 votes up - 2 votes down
Proposed Solution E - 3 votes up - 1 vote down
我想要的是通过最多UP投票对此进行排序,以便它看起来像这样:
Proposed Solution D - 7 votes up - 2 votes down
Proposed Solution E - 3 votes up - 1 vote down
Proposed Solution A - 2 votes up - 5 votes down
Proposed Solution B - 1 vote up - 0 votes down
Proposed Solution C - 0 votes up - 0 votes down
到目前为止,我有这个:
scope :most_votes_up,
select("solutions.*, count(solution_votes.id) AS votes_count").
where(['solutions.state = ?', 'Proposed']).
joins(:solution_votes).
group("solutions.id").
order("votes_count DESC")
产生这个输出:
Proposed Solution D - 7 votes up - 2 votes down
Proposed Solution A - 2 votes up - 5 votes down
Proposed Solution E - 3 votes up - 1 vote down
Proposed Solution B - 1 vote up - 0 votes down
但......我还有的问题是:
1.缺少投票的建议解决方案(显示列表中缺少上述示例中的建议解决方案C)
2.我如何仅在UP投票中指定一个计数(现在,根据哪个提议的解决方案获得MOST投票(上下),而不仅仅是向上投票?
我正在使用PostGRESQL
答案 0 :(得分:3)
使用左连接(而不是默认的内连接)来包含0关联solution_votes的解决方案。
您只需在计票中仅包括投票。
以下是我修改范围的方法:
select("solutions.*, count(solution_votes.id) AS votes_count").
joins("left join solution_votes on solution_votes.solution_id = solutions.id").
where(['solutions.state = ? and solution_votes.direction = ?', 'Proposed', 'up']).
group("solutions.id").
order("votes_count DESC")
这对您的列名做了一些假设,但您应该能够将其定制为您的实际架构而不会有太多麻烦。我也把joins
放在where
之前 - 这在技术上不会有所作为,但这是SQL需要的顺序,这对我来说更具逻辑意义。
编辑:
听起来好像你想把vot_count保持为所有选票的数量,但仍然按照投票数来排序。我不确定为什么会这样,除非你在返回的Solution对象上调用.votes_count
,但它是可能的。为此,您可以从count
聚合切换到sum
,然后执行一些处理匹配您想要计数为1的条件的记录,以及那些不匹配为0的记录。他们自己,case
表达式,如sum(case when solution_votes.direction = 'up' then 1 else 0 end)
,或做一些创意转换,将布尔值转换为整数,例如sum(cast(solution_votes.direction = 'up' as integer))
。这两个都可行 - 总和将是向上投票的总数,然后您可以在订单子句中使用。选择第一个,没有特殊原因,我们最终得到以下修订范围:
select("solutions.*, count(solution_votes.id) AS votes_count, sum(case when solution_votes.direction = 'up' then 1 else 0 end) as up_votes").
joins("left join solution_votes on solution_votes.solution_id = solutions.id").
where(['solutions.state = ? and solution_votes.direction = ?', 'Proposed', 'up']).
group("solutions.id").
order("up_votes DESC")