2011-02-13 58 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') }