我想爲使用after_initialize
的對象設置一些默認值。我遇到的問題是無論對象是如何創建的,我都希望調用它。Rails 3使用塊調用create之後,after_initialize不會運行
我的類:
class Foo < ActiveRecord::Base
serialize :data
after_initialize :init
def init
self.data ||= {}
self.bar ||= "bar"
self.baz ||= "baz"
end
end
一切正常,如果我叫Foo.new
,Foo.new(:bar => "things")
和Foo.create(:baz => 'stuff')
。但是,當我使用create
的塊時,after_initialize
回調無法運行。
obj = Foo.create do |f|
f.bar = "words"
f.data = { :attr_1 => 1, :attr_2 => 2 }
end
這只是產生obj.baz
=>nil
代替"baz"
與正確設置其他屬性。
我是否錯過了回調執行的方式,不同之處在於調用create和block之間的區別,或者是缺省值被塊所破壞?
UPDATE
發現的問題。
事實證明,調用create
與塊和無細微差別。當你在沒有塊的情況下調用create
並傳入參數散列時,對於所有意圖和目的,您要調用Foo.new({<hash of argument>}).save
,並且after_initialize
回調將在保存之前執行,就像您期望的那樣。
當你用塊調用create
時會發生一些不同的事情。事件的順序是Foo.new
被傳入的任何參數調用,然後調用after_initialize
,然後塊運行。因此,如果您正在使用塊(與我一樣)與散列參數交替使用,以增加可讀性,那麼您可以稍微調整一下,因爲在您打算設置的所有參數都已設置好之前,您的after_initialize
就會運行。
我得到了一點,因爲我在after_initialize
做了一些額外的工作,根據傳遞的值設置了一些額外的必需屬性。由於after_initialize
被調用時沒有任何設置,所以沒有設置正確,我的驗證失敗。我最後不得不打電話給init
。一旦在after_initialize
和一次在before_validation
。不是最乾淨的,但它解決了這個問題。
感謝布蘭登指引我朝着正確的方向前進。
如果你用'Foo.new'(即用聲明的塊方法)做同樣的事情,同樣的事情會發生嗎? – 2011-03-05 03:55:07
Foo.new與塊工作得很好。 – HMCFletch 2011-03-06 04:01:05
@HMCFletch - 發生了什麼的最佳解釋 - 感謝分享 – 2014-05-06 09:45:55