2012-12-01 49 views
2

我在這爲什麼User.last(2)和User.first(2)返回相同的用戶?

default_scope :order => 'created at desc' 

我現在有50條記錄,IDS 1到50

User.first回報User id: 50用戶模型。

User.first(2)回報User id: 50User id: 49

User.last回報User id: 1

這都有道理。但是,

User.last(2)返回User id: 49User id: 50,依次。這是爲什麼?如何返回User id: 1User id: 2

+0

將範圍更改爲:order =>'created_at asc' –

+0

謝謝@Jani。我想保持默認順序的方式,因爲我想保持我的索引視圖不變。但是,我希望能夠使用控制檯從列表的「頂部」和「底部」訪問用戶組,以防萬一需要進行組更新。什麼是最簡單的方法來做到這一點? – umezo

+1

您可以創建第二個作用域create_asc unscoped.order('created_at asc),然後使用User.create_asc.limit(2)。你能提供在兩種情況下執行的sql查詢嗎? – sufleR

回答

3

這是一個常見的錯誤。 User.last(1)User.last()不完全相同。 User.last(1)會給你一個單一記錄的數組,而User.last()會返回該記錄對象。

同樣,如果您的用戶模型中有default_scope,則這兩種方法的表現完全不同。

User.last只適用於您的默認範圍,顛倒其訂單。因此,它激發的SQL查詢:

SELECT * FROM users ORDER BY created_at ASC LIMIT 1 

在另一方面,User.last(1)類似於編寫User.order('id desc').limit(1)。並且在您的default_scope實際操作中,order by id desc將排在第二位。因此,它激發了SQL將是:

SELECT * FROM users ORDER BY created_at desc, id desc LIMIT 1 

那麼你真正需要做的,是刪除使用User.unscoped作爲Kien已經提及的默認範圍。 個人而言,我避免使用默認範圍排序並使用顯式範圍替代。

+0

非常感謝@atmash的詳細解答。因此,答案是取決於範圍,然後查詢'first(2)',因爲它們現在通過id排序。 – umezo

+1

不完全。第一個(N)和最後一個(N)也表現出不同的行爲。 User.last(2)會按'id desc'排序並返回前2個結果(在你的案例中爲49和50)。但User.first(2)會返回數據庫返回的前2條記錄,並且不會在SQL中應用任何顯式排序順序。有機會,你會得到用戶ID爲1和2,但你不能指望它。我建議使用User.unscoped.order(:id).first(2) – atmaish

+0

Thanks @atmaish。我想'沒有默認作用域==按ID排序,這在這種情況下對我來說是真實的,但我想明確地說'order(:id)'更安全。 – umezo

1

Rubydocs爲您提供有關第一種和最後一種方法的信息。

如果你最後一個(2)不工作,你可以嘗試

User.find(:order => 'created_at asc', :limit =>2) 

修正

User.find(:all,:order => 'created_at asc', :limit =>2) 
User.unscoped.order('created_at asc').limit(2) 

您可以通過有許多爭論得到你想要的東西。

+0

這是錯的!在Model.first()方法中使用限制選項是沒有意義的。 'first'隱式地將limit = 1添加到sql中。所以:limit => 2在你的情況下將被忽略。 – atmaish

+0

@atmaish你有權利。應該找到而不是第一個。更正了答案。 – sufleR

+0

感謝@ sufleR,但您的建議返回'ActiveRecord :: RecordNotFound:無法找到沒有ID的用戶。我使用的解決方案是User.unscoped.first(2)'。 – umezo

1

嘗試unscoped方法:

User.unscoped.first(2) # Get User id=1 and id=2 

您可以檢查Remove all scoping

+0

謝謝@Kien。事實上,它實際上是'User.unscoped.first(2)',因爲它現在是按ID排序的,而ID 1和2現在開始。 – umezo

+1

哦,我看到你的問題'User.last(2)返回用戶ID:49和用戶ID:50' :) :),讓我更新答案。 – Thanh

相關問題