2012-08-24 16 views
4

我正在運行Rails 3.2.8和ruby 1.9.3p194。ActiveRecord關係存在混淆?方法,特別是有限制和偏移量

我試圖更好地理解存在的方式?方法在主動記錄中工作。我收到了一些我不明白的奇怪結果......爲了清晰起見,我將在這裏簡化我的代碼。

想象一下,我有一個包含用戶列表的用戶模型。

1安迪,米
2傑克,米
3凱西,F
4麥克,米

我有男性一個範圍,因此:

User.male => [#< User id: 1, name: Andy, gender: male>, #< User id: 2, name: Jake, gender: male>, #< User id: 4, name: Mike, gender: male>] 

確定。現在:

a = User.find 1 => #<User id: 1, name: Andy, gender: male> 
b = User.find 2 => #<User id: 2, name: Jake, gender: male> 
c = User.find 3 => #<User id: 3, name: Cathy, gender: female> 
d = User.find 4 => #<User id: 4, name: Mike, gender: male> 

User.male.exists?(a) => true 
User.male.exists?(b) => true 
User.male.exists?(c) => false 
User.male.exists?(d) => true 

好吧,這是有道理的。但是:

User.male.limit(1) => [#<User id: 1, name: Andy, gender: male>] 

User.male.limit(1).exists?(a) => true 
User.male.limit(1).exists?(b) => true 
User.male.limit(1).exists?(c) => false 
User.male.limit(1).exists?(d) => true 

爲什麼存在?(b)和存在?(d)返回true?是否因爲限制實際上並沒有改變仍然是所有男性用戶的查詢,並且限制(1)僅僅是顯示事物?我可以買這個,但是如果我只想要存在,那麼正確的查詢會是什麼?(a)返回true,其他所有返回false?

好了,現在這真的讓我困惑徹底:

User.male.limit(1).offset(1) => [#<User id: 2, name: Jake, gender: male>] 

User.male.limit(1).offset(1).exists?(a) => false 
User.male.limit(1).offset(1).exists?(b) => false 
User.male.limit(1).offset(1).exists?(c) => false 
User.male.limit(1).offset(1).exists?(d) => false 

爲什麼這裏的一切返回false?我想要存在嗎?(b)迴歸真實,而我根本弄不清楚爲什麼它不存在。如果有人能夠啓發我,我會非常感激。我翻看文檔無濟於事。

回答

1

User.male增加了一個where子句 「性別=男」

.exists?(a)增加了一個額外條款 「ID = 1」

limit 1只是增加了一個limit 1 where子句後。

所以User.male.limit(1).exists?(a)會產生 SELECT 1 FROM用戶WHERE用戶. ID = 1 AND (gender =男性) LIMIT 1

那麼,爲什麼.exists?(x)的作品,是因爲它添加了ID的where子句,因此有理由選擇相關記錄。

此外,offset(1)將無法​​正常工作,因爲當您放入exists?(x)並添加一個偏移量(1)時,只會得到1個匹配的記錄,這意味着它應該在那之後查找記錄。

+0

好的,這對我有意義。因此,有沒有一種方法可以創建一個查詢(或方法)來獲得我想要的答案?我想查看activerecord關係的結果,看看裏面是否有記錄。 – kindofgreat

+0

其實我發現了一些可行的東西。如果我使用ar:relation並將其更改爲數組,那麼我可以使用include?所以:User.male.limit(1).offset(1).to_a.include?(x)得到我正確的結果。這是做這件事的最好方法嗎?還是有更高效的SQL /其他方式? – kindofgreat

+0

另外,我剛剛讀到Set的包含?比Array的速度快,所以我將它改爲User.male.limit(1).offset(1).to_set.include?(x)...也許還有一種更快的SQL方法,或者也許to_a是比to_set更快,並且沒有性能優勢。無論如何.... – kindofgreat