我有一個觀察者,我註冊了一個after_commit
回調。 如何判斷在創建或更新後是否被解僱? 我可以通過詢問item.destroyed?
來告訴某件物品被毀壞,但#new_record?
自該物品被保存後不起作用。Rails 3:如何識別觀察者中的after_commit動作? (創建/更新/銷燬)
我正要加入after_create
/after_update
解決它,這樣做@action = :create
內,並檢查@action
在after_commit
,但似乎觀察者實例是單身,我可能只覆蓋一個值它到達之前after_commit
。所以我以一種更醜陋的方式解決了這個問題,將action放在基於after_create/update上的item.id的映射中,並在after_commit上檢查它的值。真的很醜。
有沒有其他辦法?
更新
正如@tardate說,transaction_include_action?
是一個很好的跡象,但它是一個私有方法,並以觀察員應該與#send
訪問。
class ProductScoreObserver < ActiveRecord::Observer
observe :product
def after_commit(product)
if product.send(:transaction_include_action?, :destroy)
...
不幸的是,:on
選項不適用於觀察者。
只要確保你測試了觀察者的地獄(如果你使用use_transactional_fixtures,查找test_after_commit
gem),所以當你升級到新的Rails版本時,你會知道它是否仍然有效。
(測試3.2.9)
更新2
相反觀察員我現在請使用ActiveSupport ::關注和after_commit :blah, on: :create
那裏工作。
當after_commit被解僱時,你是否想知道你的記錄是否是新的?重新閱讀你的問題和答案,我覺得很困惑。你可以重述一下嗎?或者給我們一個清晰的例子嗎? – charlysisto
如果您使用單線程服務器,則您的初始解決方案可以正常工作。如果你不使用它,然後切換到一個,如獨角獸,這將以一種乾淨的方式解決這個問題。它使得編程模型變得容易得多,你將會減少頭痛(像這樣),最終它會更快。使用+ transaction_include_action?+不是乾淨的,因爲它是一個不受rails測試套件中任何測試支持的不受支持的受保護的rails方法。下一個版本可能沒有這種方法。 –
@elado我很困惑。接受的答案(tardate's)不適用於觀察者(正如ches的評論所指出的那樣)。你是否轉而使用回調呢?請附上對您的問題的解釋。 – Kelvin