【问题标题】:Rails Active Record has nil id after commitRails Active Record 在提交后具有 nil id
【发布时间】:2015-08-26 07:11:12
【问题描述】:

我为我的一个 Active Record 实体注册了一个 after_commit 触发器,如下所示:

class Work < ActiveRecord::Base
    after_commit :on_work_commit

    ...

    def on_work_commit
        puts self.id # prints nil sometimes
    end
end

问题是在我的生产环境中,self.id 有时是 nil 在 on_work_commit 方法中。它不会一直发生,实际上,它会间歇性地发生。通过分析这些错误的堆栈跟踪,我可以看到它们在作品创建操作期间间歇性地发生,但在更新作品时从未发生。我无法在本地重现此问题,因为它仅在同时创建和更新大量作品时才会在生产中发生。

这种问题对我来说是竞争条件,但我不知道可能出了什么问题。是否存在在对象获得 id 之前可以为对象调用 after_commit 触发器的情况?

我使用的是 rails 3.2.22 版和 ruby​​ 1.9.3-p484 版。

【问题讨论】:

  • 您找到解决方案了吗?
  • 还没有!我们暂时忽略它,稍后再讨论。一旦我们找出原因,我会立即更新。
  • 您的测试是否包含在事务中,例如use_transactional_fixtures 或数据库清理事务策略。更改为截断可能会有所帮助。但是,如果您的 after_commit 被解雇,您就不能将测试包装在事务中......

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


【解决方案1】:

after_commit 方法也会为destroy 操作执行,这就是为什么当您尝试删除项目时它会返回nil,而是这样做

after_commit :on_work_commit, on: [:create, :update]

我建议您为此使用after_save

after_save :on_work_commit

希望有帮助!

【讨论】:

  • 遗憾的是,这些错误与销毁操作无关。 Work 实体具有确保它永远不会被破坏的机制,而是被软删除。此外,on_work_commit 方法中的代码在工作的 id 为 nil 时会引发错误,这会生成一个堆栈跟踪,告诉我在创建工作时发生了错误。
  • 尝试改用 after_save
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-04
相关资源
最近更新 更多