TL;博士?见编辑 2
我有一个小的 Rails 应用程序,它有一些人们可以玩的不同类型的游戏:它基于体育,所以他们可以每周挑选每场比赛的获胜者(模型 PickEm
,属性 correct
bool 值,未完成游戏的属性为 nil
),并预测特定球队比赛的结果(模型 Guess
,属性 score
为整数,nil
为未完成的比赛)。每个 User
has_many
PickEms
和 Guesses
。而且我正在尝试显示排名( correct
/total - total 都是非 nil
, score
/total 可能)。
我发现我可以收集用户及其相关记录,但在尝试显示排名时,我发现每个用户都在触发另一个查询 - 随着用户群的增加,速度缓慢且不可持续。那是因为 @user.pick_em_score
是 pick_ems.where(correct: true).size
而 @user.guess_Score
是 guesses.where.not(score: nil).sum(:score)
。所以我调用 user.pick_em_score
并运行该查询。我觉得应该有一种方法可以一次获取每个 User
以及这些特定计数,而不是缓冲一大堆不必要的额外内容。
我需要的:
User
记录 User.pick_em_score
(计算correct
条记录) User.pick_ems
计数在哪里 NOT NULL
User.guesses_score
(由guesses.sum(:score)
计算) User.guesses
计数在哪里 NOT NULL
我在 Rails 的 ActiveRecord 助手中找到的大部分内容,尤其是与计算相关的内容,都是仅用于检索计算。看起来我可能需要直接深入研究
select()
等。但我无法让它工作。有人可以指出我正确的方向吗?编辑
澄清一下:我知道我可以将此信息写入
User
模型,但这过于严格:下个赛季,我需要在 User
中添加一个新列以获取当年的结果等。此外,这个是第三级回调更新相关模型——Match
模型在保存时已经更新了相关的 PickEms
和 Guesses
。 我正在寻找最简单的 ActiveRecord 查询或能够处理此信息的查询,如标题所示。 理想情况下一个查询返回上述信息,但如果需要几个,那没关系。我以前使用 PHP 直接在 MySQL 中工作,但这些技能已经生锈了(我想,在原始 MySQL 中,我会有几个子选择语句来帮助提取这些计数),我也希望能够使用 Rails 的ActiveRecord 助手等,并尽可能避免构建原始 SQL。
第二次编辑:
我似乎把它归结为一个开始工作的调用,但我正在写很多 SQL。 它也很脆弱,IMO,尝试运行它失败了。看起来我只是将 Rails 中的百万个单数
SELECT
查询直接推送到 SQL 中,但这可能仍然是一个进步。User.unscoped.select('users.*',
'(SELECT COUNT(*) FROM pick_ems WHERE pick_ems.user_id = users.id AND pick_ems.correct) AS correct_pick_ems',
'(SELECT COUNT(*) FROM pick_ems WHERE pick_ems.user_id = users.id AND pick_ems.correct IS NOT NULL) AS total_pick_ems',
'(SELECT SUM(guesses.score) FROM guesses WHERE guesses.user_id = users.id AND guesses.score IS NOT NULL) AS guesses_score',
'(SELECT COUNT(*) FROM guesses WHERE guesses.user_id = users.id AND guesses.score IS NOT NULL) AS guesses_count' )
问题似乎是: 有没有一种方法可以使用 Rails 而不是原始 SQL 来链接我们在那里看到的
users.id
和这些子查询 ?或者只是……一般来说是一种更好的构建方法?此外,我正在为
SELECT
运行另一组 WHERE
,这将取决于 total_pick_ems
和 guesses_count
是 > 0
但由于我不能使用这些别名列,我必须再调用一次 SELECT
。
最佳答案
欢迎来到 AR。它真的只适用于简单的 CRUD 之类的查询。一旦您真的想愤怒地查询您的数据,它就没有能力执行您想要的查询,而无需求助于批发 SQL 字符串,因此通常会放弃链接的能力。
这正是我转向 Sequel 的原因,因为它确实具有使用更完整的 SQL 功能集组合查询的功能,包括连接条件、窗口函数、递归公用表表达式和高级预加载。与 AR 和 Arel 相比,作者 react 迅速,文档也非常出色。
我不希望您会喜欢这个答案,但总有一天,您会开始关注带有 rails 的自以为是的组件,我不得不说这些组件几乎不是同类产品中最好的。 Sequel 还使我的应用程序速度比我使用 AR 能够获得的速度快很多倍,这不仅是开发人员的快乐,还意味着可以运行的服务器更少。是的,这将是一个学习曲线,但 IMO 最好学习有你支持的工具。
关于mysql - 一次查询 ActiveRecord 的记录和关系计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26577573/