2014-11-21 34 views
6

我看到的Rails find方法採取塊作爲滑軌找到與塊

Consumer.find do |c| 
    c.id == 3 
end 

其類似於Consumer.find(3)。

有哪些的使用情況下,我們實際上可以使用塊的find

回答

12

它是.to_a.find { ... }一個快捷方式的示例查詢。下面是該方法的source code

def find(*args) 
    if block_given? 
    to_a.find(*args) { |*block_args| yield(*block_args) } 
    else 
    find_with_ids(*args) 
    end 
end 

如果傳遞一個塊,它調用.to_a(加載所有記錄),並在陣列上調用Enumerable#find

換句話說,它允許您在ActiveRecord::Relation上使用Enumerable#find。如果您的條件無法在SQL中表達或評估,那麼這非常有用,例如查詢serialized attributes

Consumer.find { |c| c.preferences[:foo] == :bar } 

爲了避免混淆,我寧願更明確的版本,雖然:

Consumer.all.to_a.find { |c| c.preferences[:foo] == :bar } 
+0

但是'沒有定義Consumer.to_a',是嗎?從ActiveRecord :: Base繼承的類不是ActiveRecord :: Relation的實例。 – 2014-11-21 08:27:49

+0

@你說得對,你必須調用'.all.to_a'。我應該測試我的代碼。 – Stefan 2014-11-21 08:55:33

4

結果可以是相似的,但SQL查詢不類似於Consumer.find(3)

據獲取所有的消費者然後過濾基於所述塊上。我想不出用例的情況可能是有用的

下面是在控制檯

consumer = Consumer.find {|c|c.id == 2} 
# Consumer Load (0.3ms) SELECT `consumers`.* FROM `consumers` 
# => #<Consumer id: 2, name: "xyz", ..>