嘗試成爲DRY,我試圖在對象初始化後分配給模型的實例變量。after_initialize導致堆棧溢出
class WorkNote < ActiveRecord::Base
def after_initialize
self[:clockin]= WorkNote.last_clockout
end
def self.last_clockout
WorkNote.find(:first, :order => "clockout DESC").clockout
end
end
然而,在after_initialize
方法調用導致SystemStackError
:
ActiveRecord::StatementInvalid: SystemStackError: stack level too deep: SELECT * FROM "work_notes" ORDER BY clockout DESC LIMIT 1
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.2/lib/active_record/connection_adapters/abstract_adapter.rb:212:in `log'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.2/lib/active_record/connection_adapters/sqlite_adapter.rb:157:in `execute'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.2/lib/active_record/connection_adapters/sqlite_adapter.rb:402:in `catch_schema_changes'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.2/lib/active_record/connection_adapters/sqlite_adapter.rb:157:in `execute'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.2/lib/active_record/connection_adapters/sqlite_adapter.rb:305:in `select'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:7:in `select_all_without_query_cache'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.2/lib/active_record/connection_adapters/abstract/query_cache.rb:62:in `select_all'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.2/lib/active_record/base.rb:661:in `find_by_sql'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.2/lib/active_record/base.rb:1553:in `find_every'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.2/lib/active_record/base.rb:1510:in `find_initial'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.2/lib/active_record/base.rb:613:in `find'
from /Users/noob/jobs/app/models/work_note.rb:10:in `last_clockout'
from /Users/noob/jobs/app/models/work_note.rb:6:in `after_initialize'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.2/lib/active_record/callbacks.rb:347:in `send'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.2/lib/active_record/callbacks.rb:347:in `callback'
from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.2/lib/active_record/base.rb:1662:in `send'
... 5116 levels...
如果我註釋掉after_initialize
,該last_clockout
方法沒有任何問題。當我使用before_save
而不是after_initialize
這樣的回調時,也不會發生這種情況。爲什麼after_initialize
造成這種情況?
謝謝!
謝謝你的幫助的答覆!我得到了什麼問題。雖然'default_value_for'不會有同樣的問題嗎?似乎只要屬性的初始值需要find(),新的WorkNote對象將不得不被實例化,並且循環將繼續發生。 我可以這樣想的其他方式: a。在控制器中分配初始值,儘管這不是它所屬的區域 b。將默認值存儲在另一個模型中,如用戶 有沒有其他建議?謝謝! – rahum 2009-08-24 17:25:19
default_value_for通過重寫getter並僅在缺少值時才提供缺省值來工作。它實際上並沒有改變數據庫或底層對象的值。由於default_value_for在創建對象時不會自動運行(僅當訪問該列時),因此無法像原始問題那樣使用這種方法進行遞歸。 – Luke 2009-08-25 00:04:45