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

时间:2018-12-13 17:06:52

标签: ruby-on-rails ruby postgresql activerecord rails-activerecord

我有一个极端的情况,我想只在执行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的骇客解决方案,但是我真的很想知道在调用.first之前是否有适当的方法来强制执行。

2 个答案:

答案 0 :(得分:1)

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

  

“查找第一个记录(如果提供了参数,则查找第N个记录)。如果未定义顺序,它将通过主键进行排序。”

代替尝试take

  

“给出一条记录(如果提供了参数,则提供N条记录),而没有任何隐含的顺序。该顺序将取决于数据库的实现。如果提供了顺序,则将予以遵守。”

所以

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 }

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

答案 1 :(得分:1)

您可能想使用pluck而不是select来检索数据,https://www.datastax.com/dev/blog/lightweight-transactions-in-cassandra-2-0只是更改将哪些字段加载到 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

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