Rails:使用ActiveRecord .first查询时省略order by子句?

时间:2016-10-18 17:46:14

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

我在Rails 4 ActiveRecord中遇到.first查询问题。 Rails 4中的新行为是在id字段中添加顺序,以便所有数据库系统都输出相同的顺序。

所以这......

Foo.where(bar: baz).first

将提供查询......

select foos.* from foos order by foos.id asc limit 1

我遇到的问题是我的选择包含两个和字段。在查询中自动抛出 id by id 时,我收到一个错误,即id字段必须出现在group by子句中。错误是正确的,如果我希望输出是这两个字段的总和,则不需要id字段。

这是一个不起作用的例子......

baz = Foo.find(77).fooviews.select("sum(number_of_foos) as total_number_of_foos, sum(number_of_bars) as total_number_of_bars").reorder('').first

这是错误......

  

ActiveRecord :: StatementInvalid:PG :: GroupingError:ERROR:column" foos.id"必须出现在GROUP BY子句中或用于聚合函数       第1行:...吧来自" fooviews" ORDER BY" ...

由于select是一个聚合表达式,因此不需要id 的顺序,但是AR会自动抛出它。

我发现我可以在.first之前添加重新排序(''),并按ID删除顺序 ,但这是解决这个问题的正确方法吗?

谢谢

[更新] 我忽略的是我将大型Rails 3项目转换为Rails 4.因此Rails 3的输出是一个AR对象。如果可能的话,我希望解决方案保持这种格式,以便在转换中更改代码更少。

1 个答案:

答案 0 :(得分:5)

您需要使用take

  

take方法检索没有任何隐式排序的记录。

例如:

baz = Foo.find(77).fooviews.select("sum(number_of_foos) as total_number_of_foos, sum(number_of_bars) as total_number_of_bars").take

提交消息here表示这是旧first行为的替代。