gpt4 book ai didi

ruby-on-rails - Rails 3 : How to identify after_commit action in observers?(创建/更新/销毁)

转载 作者:行者123 更新时间:2023-12-03 05:40:36 25 4
gpt4 key购买 nike

我有一个观察者,并且注册了一个 after_commit 回调。如何判断它是在创建还是更新后被触发?我可以通过询问 item.destroyed? 得知某个项目已被销毁,但 #new_record? 由于该项目已保存而不起作用。

我打算通过添加 after_create/after_update 来解决这个问题,并在内部执行类似 @action = :create 的操作并检查 @action at after_commit,但观察者实例似乎是一个单例,我可能只是在它到达 after_commit 之前重写一个值。所以我用一种更丑陋的方式解决了这个问题,根据 after_create/update 上的 item.id 将操作存储在 map 中,并在 after_commit 上检查其值。真的很丑。

还有其他办法吗?

更新

正如@tardate所说,transaction_include_action?是一个很好的指示,尽管它是一个私有(private)方法,并且在观察者中应该使用#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::Concern 代替观察者,并且 after_commit :blah, on: :create 在那里工作。

最佳答案

我认为transaction_include_action?就是你所追求的。它可靠地指示了正在处理的特定事务(已在 3.0.8 中验证)。

正式地,它确定事务是否包含 :create、:update 或 :destroy 操作。用于过滤回调。

class Item < ActiveRecord::Base
after_commit lambda {
Rails.logger.info "transaction_include_action?(:create): #{transaction_include_action?(:create)}"
Rails.logger.info "transaction_include_action?(:destroy): #{transaction_include_action?(:destroy)}"
Rails.logger.info "transaction_include_action?(:update): #{transaction_include_action?(:update)}"
}
end

同样感兴趣的可能是 transaction_record_state它可用于确定事务中是否创建或销毁了记录。状态应该是 :new_record 或 :destroyed 之一。

Rails 4 更新

对于那些寻求解决 Rails 4 中问题的人,此方法现已弃用,您应该使用 transaction_include_any_action? ,它接受操作的 array

使用示例:

transaction_include_any_action?([:create])

关于ruby-on-rails - Rails 3 : How to identify after_commit action in observers?(创建/更新/销毁),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7238699/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com