我有三个看起来像这样的模型(我只是留下了对问题很重要的东西):
class Symbol < ActiveRecord::Base
has_many :mnemonic
end
class Mnemonic < ActiveRecord::Base
belongs_to :symbol
has_many :mnemonic_votes
end
class MnemonicVote < ActiveRecord::Base
belongs_to :mnemonic
attr_accessible :vote_up
end
:vote_up属于boolean类型,如果为true,则表示有人对助记符进行了投票,如果为false则表示有人对其进行了投票。
我想通过投票差异获得前三名助记符。假设数据库中有5个助记符记录,其中上/下投票数量如下(MnemonicVote记录的真/假为:vote_up字段):
mnemonic up down total
mnemonic1 3 2 1
mnemonic2 17 3 14
mnemonic3 2 5 -3
mnemonic4 11 7 4
mnemonic5 5 5 0
我想按降序获得以下三个助记符(带计数):
mnemonic2 14
mnemonic4 4
mnemonic1 1
我写了这个实际的代码,它给了我想要的结果,但我知道它很糟糕,我不喜欢我是怎么做的,因为数据在所有MnemonicVote之后被分组并排序与证书助记符记录关联的记录从DB中获取:
@mnemonics = Mnemonic.where(symbol_id: self.id) # here I fetch all Mnemonics associated with Symbol table
@mnemonics.sort_by { |mnemonic| mnemonic.votes_total }.reverse!
return @mnemonics.take(3)
其中mnemonic.votes_total是助记符对象的计算属性。我想通过使用单个AR(甚至SQL)查询获得相同的结果。如何实现这一目标?感谢。
答案 0 :(得分:0)
我相信这就是你想要的:
Mnemonic.
joins(:mnemonic_votes).
select("mnemonics.*, SUM(IF(mnemonic_votes.upvote, 1, -1)) AS vote").
group("mnemonics.id").
order("vote DESC").
map { |m| [m.symbol, m.vote.to_i] }
答案 1 :(得分:0)
两个答案都在正确的轨道上,除了不能与PostgreSQL一起使用的IF子句(如果(布尔,整数,整数)不存在,我会得到函数)。如果有人需要,这是我的最终解决方案:
Mnemonic.
select("mnemonics.*, SUM(CASE WHEN mnemonic_votes.vote_up THEN 1 ELSE -1 END) AS votes_total").
joins(:mnemonic_votes).
where(symbol_id: self.id).
group("mnemonics.id").
order("votes_total DESC").
limit(3)