2011-02-13 37 views
14

我在Heroku部署中遇到了一个奇怪的问题,我似乎无法在本地重复。基本上,当我在一个特定的模型上找到所有的东西而不是用ID进行排序时,它似乎完全没有返回它们。ActiveRecord查找全部不按ID排序?

通常记录出来,像这样:

>> Model.all 

=> [<model id: 2>,<model id: 1>,<model id: 3>,<model id: 4>,<model id: 5>] 

...等等。

如果我明确地调用Model.order("id ASC"),它将按照预期返回模型。

什么给?为什么会找到所有不按ID降序返回对象?

回答

23

按ID排序的是而不是默认情况下会有保证,因为它取决于数据库如何排序(通常未指定)非订购查询。你可以把它随时通过模型的顶端定义default scope像这样被下令:

default_scope { order('id ASC') } 

然后调用Model.all将相当于调用Model.order('id ASC')

+0

这会改变您所有的疑问,我把一个方式做一些额外的方法作为扩展[这里](http://stackoverflow.com/a/22906452/1802527)适用于所有型号 – Alexis 2014-04-07 08:18:18

+0

首先,在新版本的Rails中,这应该是`default_scope {order id::asc}`吗?另外,这是否容易受到`default_scope`模型初始化问题的影响? – BalinKingOfMoria 2016-02-18 18:10:31

7

在SQL中,表被认为是记录集,不列表的记录,以及“选择”的查询不能保证在任何特定的顺序返回记录,除非一个“顺序通过”子句具体包括在内。有时您可能会碰巧看到结果按特定顺序返回,但这并不意味着您可以或应该假设结果总是如此。

使用ActiveRecord,如果您喜欢,可以通过指定默认范围来强制使用默认的'order by'子句。一般来说,这是一个坏主意,因为它会迫使服务器做更多的工作来给你一个排序的结果集,即使你不需要排序。此外,'id'字段中的排序通常是不恰当的,因为'id'的点是一个不透明的记录标识符,没有任何目的或含义,除了对于表中的给定记录是唯一的。

0

好吧,备案我的测试中取得了如下解释:在PostgreSQL上(可能还有其他人)似乎回报的事情在他们的最后的保存顺序“所有”的方法(见下面的评论)。所以,最近保存的项目返回最后一个,最早的保存项目首先返回。我能够通过以ID顺序重新保存所有模型来“修复”订单。

这个问题在SQLite等上不存在,但史蒂夫的回答是有道理的(不保证记录会以特定的顺序返回)。另外,安德鲁马歇尔的答案确实奏效。

2

只是Andrew最佳答案的更新(对不起,我没有足够的声望添加为评论),现在删除了不带块的调用#default_scope的支持。目前在型号可接受的语法是:

default_scope { sort(id: 'ASC') }