Rails - 创建回调和嵌套属性后的执行顺序

pra*_*vin 12 ruby-on-rails callback model-associations after-create

我有一个简单的设置UserUserProfile模型与User has_one :user_profile和UserProfile belongs_to :user.

但我无法理解Rails如何定义after_create回调的执行顺序并accepts_nested_attributes_for在我的模型中定义.让我们考虑这两种情况.

情况1:

class User < ActiveRecord::Base
  has_one :user_profile
  accepts_nested_attributes_for :user_profile
  after_create :test_test
end
Run Code Online (Sandbox Code Playgroud)

现在,如果我通过控制台创建用户(也使用user_profile_attributes哈希),after_create则会在创建用户及其用户配置文件后触发回调.

案例2: 如果after_create放在顶部,

class User < ActiveRecord::Base
  after_create :test_test
  has_one :user_profile
  accepts_nested_attributes_for :user_profile
end
Run Code Online (Sandbox Code Playgroud)

在创建用户之后但在创建用户配置文件之前触发回调.

这是它预期运作的方式.Rails在这里做什么?执行顺序是否仅由代码的顺序决定?

我在哪里开始深入研究或调试这个?

Yve*_*enn 10

模型中声明的顺序可能会影响代码的执行顺序.这是各种怪异事物的来源.(例如,当前的回调定义和has_and_belongs_to_many关联是依赖于顺序的:https://github.com/rails/rails/pull/8674)

要调试此问题,您需要浏览rails源.由于您的问题与执行顺序,回调和嵌套属性有关,我将从阅读开始:

这为您提供了深入挖掘的必要背景.您会注意到accepts_nested_attributes_for调用add_autosave_association_callbacks https://github.com/rails/rails/blob/master/activerecord/lib/active_record/autosave_association.rb#L173 此方法会添加after_create回调,据我所知,回调按顺序执行定义.

  • 谢谢.这正是我遇到的.我的模型有after_create回调运行,它们被放在has_many定义之前.在after_create中,我使用update_attribute(在某些情况下)更新了一个属性,然后导致has_many链的其余部分无法更新,这意味着我的has_many:通过关系不保存任何内容.在我的关系定义之后移动after_create修复了问题.疯.谢谢!!! (2认同)