我可以强制执行活动记录查询链吗?

Can I force the execution of an active record query chain?

我有一个极端情况,我想在 我的 SQL 查询执行后才使用 .first

我的案例是下一个:

User.select("sum((type = 'foo')::int) as foo_count",
            "sum((type = 'bar')::int) as bar_count")
    .first
    .yield_self { |r| r.bar_count / r.foo_count.to_f }

但是,这会引发 SQL 错误,提示我应该在 GROUP BY 子句中包含我的 user_id。我已经找到了一个使用 to_a 的 hacky 解决方案,但我真的想知道在调用 .first.

之前是否有适当的方法强制执行

错误是因为 first 使用 order by 语句来按 id 排序。

"Find the first record (or first N records if a parameter is supplied). If no order is defined it will order by primary key."

尝试 take

"Gives a record (or N records if a parameter is supplied) without any implied order. The order will depend on the database implementation. If an order is supplied it will be respected."

所以

User.select("sum((type = 'foo')::int) as foo_count",
        "sum((type = 'bar')::int) as bar_count")
.take
.yield_self { |r| r.bar_count / r.foo_count.to_f }

应该可以正常工作,但如前所述,顺序不确定。

您可能想要使用 pluck which retrieves only the data instead of select,它只会改变加载到 models:

中的字段
User.pluck(
  "sum((type = 'foo')::int) as foo_count",
  "sum((type = 'bar')::int) as bar_count"
).map do |foo_count, bar_count|
  bar_count / foo_count.to_f 
end

如有必要,您也可以在查询中进行除法。