让我们看看,也许我至少可以给你一个 SQL 查询,然后我们可以担心 ActiveRecord 化它:
SELECT resources.*, sum(case views.vote when 'up' 1 else 0 end) as up_votes, count(views.id) as total_views
FROM resources
JOIN views ON views.resource_id = resources.id
JOIN rates ON rates.resource_id = resources.id
AND rates.user_id = views.user_id
WHERE views.updated_at - views.created_at >= interval '5 minutes'
AND views.vote IS NOT NULL
GROUP BY resources.id
现在,我当然不能完全确定这是对的,但这可能是一个开始。然后,您可以将其分解为 ActiveRecord 形式:
@resources = Resources.
select("resources.*, sum(case views.vote when 'up' 1 else 0 end) as up_votes, count(views.id) as total_views").
joins("JOIN views ON views.resource_id = resources.id JOIN rates ON rates.resource_id = resources.id AND rates.user_id = views.user_id").
where("views.updated_at - views.created_at >= interval '5 minutes' AND views.vote IS NOT NULL").
group("GROUP BY resources.id")
up_votes
and将total_views
附加到每个 Resource 对象,因此您可以调用和操作它们(我发现它们由于某种原因被转换为字符串,因此您可能需要在它们.to_f
上使用:
ratios = @resources.map{|r| r.up_votes.to_f/r.total_views.to_f}
select
如果您希望数据库按比率或其他方式排序,您也可以在 中进行除法。
如果您实际上只是想要所有资源的比率,只需取出分组(尽管我不知道 ActiveRecord 会参与其中,除非它提供与数据库的连接)。