我有一个观察者,我注册了一个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