【问题标题】:Is there a way to trigger a callback on a Rails model only after a commit has happened for a create?有没有办法仅在创建提交后触发 Rails 模型上的回调?
【发布时间】:2014-02-23 06:25:15
【问题描述】:

我从after_create 回调中调用“队列”方法,以在模型实例创建后触发Sidekiq 进程。但是,我的 Sidekiq 工人第一次接手工作时,记录还没有提交。

我知道有一个after_commit 记录,但我只希望对象在创建时排队,而不是在更新时排队。如果没有涉及日期检查等的任何黑客行为,我如何才能做到这一点?

【问题讨论】:

  • 引入睡眠?这也可能有效(再次破解)。
  • 这至少会减少失败。
  • 如何在after_commit 方法中检查#id_was。如果是新记录,也许应该是nil

标签: ruby-on-rails-3.2 callback rails-activerecord


【解决方案1】:

你可以在before_create回调中设置一个标志

before_create :set_new_flag
after_commit :queue

def set_new_flag
  @__new_flag = true
end

def queue
  if defined? @__new_flag
    #queue it up
    remove_instance_variable(:@__new_flag)
  end
  # puts self.previous_changes
end

或者只检查after_commit 中的#previous_changes。 id 键中的 nil 应该只用于 new_records。这是previous_changes的示例输出

{"name"=>[nil, "newest"], "id"=>[nil, "cBdjzQgxir45xQJ9UXGRSR"], "version_id"=>[nil, "cBdnAogxir45xQJ9UXGRSR"]}

【讨论】:

    【解决方案2】:

    正确的方法是使用:on选项:

    after_commit :queue, :on => :create
    

    更多:http://api.rubyonrails.org/v3.2.13/classes/ActiveRecord/Transactions/ClassMethods.html#method-i-after_commit

    【讨论】:

    • 这看起来像是要走的路。任何人都可以确认这可以解决问题吗?
    • @JoshPinter 为我工作!我已经在几个代码库中使用了它,其中 sidekiq 正在获取尚未提交到数据库的作业 ID。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-31
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-18
    • 1970-01-01
    相关资源
    最近更新 更多