我遇到了一個奇怪的問題,創建一個範圍和使用first
發現者。看起來好像在作用域中使用first
作爲查詢的一部分將使其返回所有結果,如果未找到結果。如果找到任何結果,它將正確返回第一個結果。Rails範圍返回全部而不是零
我已經建立了非常簡單的測試來證明這一點:
class Activity::MediaGroup < ActiveRecord::Base
scope :test_fail, -> { where('1 = 0').first }
scope :test_pass, -> { where('1 = 1').first }
end
請注意這個測試,我已經設置好條件匹配的記錄或沒有。實際上,我是根據實際情況進行查詢,並得到相同的奇怪行爲。
以下是失敗範圍的結果。正如你所看到的,它使正確的查詢,其中有沒有結果,所以這則所有匹配的記錄,並返回的查詢代替:
irb(main):001:0> Activity::MediaGroup.test_fail
Activity::MediaGroup Load (0.0ms) SELECT "activity_media_groups".* FROM "activity_media_groups" WHERE (1 = 0) ORDER BY "activity_media_groups"."id" ASC LIMIT 1
Activity::MediaGroup Load (0.0ms) SELECT "activity_media_groups".* FROM "activity_media_groups"
=> #<ActiveRecord::Relation [#<Activity::MediaGroup id: 1, created_at: "2014-01-06 01:00:06", updated_at: "2014-01-06 01:00:06", user_id: 1>, #<Activity::MediaGroup id: 2, created_at: "2014-01-06 01:11:06", updated_at: "2014-01-06 01:11:06", user_id: 1>, #<Activity::MediaGroup id: 3, created_at: "2014-01-06 01:26:41", updated_at: "2014-01-06 01:26:41", user_id: 1>, #<Activity::MediaGroup id: 4, created_at: "2014-01-06 01:28:58", updated_at: "2014-01-06 01:28:58", user_id: 1>]>
其他範圍按預期運行:
irb(main):002:0> Activity::MediaGroup.test_pass
Activity::MediaGroup Load (1.0ms) SELECT "activity_media_groups".* FROM "activity_media_groups" WHERE (1 = 1) ORDER BY "activity_media_groups"."id" ASC LIMIT 1
=> #<Activity::MediaGroup id: 1, created_at: "2014-01-06 01:00:06", updated_at: "2014-01-06 01:00:06", user_id: 1>
如果我在範圍之外執行相同的邏輯,我會得到預期的結果:
irb(main):003:0> Activity::MediaGroup.where('1=0').first
Activity::MediaGroup Load (0.0ms) SELECT "activity_media_groups".* FROM "activity_media_groups" WHERE (1=0) ORDER BY "activity_media_groups"."id" ASC LIMIT 1
=> nil
我在這裏錯過了什麼嗎?這看起來像Rails/ActiveRecord/Scopes中的一個bug,除非有一些未知的行爲期望。
'.first'返回一個記錄,而不是阿雷爾,對不對? – Satya
您正在使用哪種版本的ruby和rails? – shiva
@shiva - Rails 4和Ruby 2.0 – Ryan