【问题标题】:What is the order of ActiveRecord callbacks and validations?ActiveRecord 回调和验证的顺序是什么?
【发布时间】:2012-06-10 14:51:51
【问题描述】:
我想知道在创建 ActiveRecord 对象时调用回调和验证的顺序是什么。
假设我有一些自定义验证和回调,如下所示:
validates :reference_code, :if => :reference_code, :on => :create
before_create :assign_reference
哪个会先运行?回调需要先发生,否则验证可能会失败。
【问题讨论】:
标签:
ruby-on-rails
ruby-on-rails-3
validation
activerecord
【解决方案1】:
最新版本的 Rails 列表的最新版本可以在ActiveRecord::Callbacks documentation 中找到。 Rails 4、3 和 2 的列表如下。
导轨 4
此列表的最新版本可在Rails 4 Guides 中找到。
创建一个对象
before_validation
after_validation
before_save
around_save
before_create
around_create
after_create
after_save
after_commit/after_rollback
更新对象
before_validation
after_validation
before_save
around_save
before_update
around_update
after_update
after_save
after_commit/after_rollback
销毁对象
before_destroy
around_destroy
after_destroy
after_commit/after_rollback
导轨 3
此列表的最新版本可在Rails 3 Guides 中找到。
创建一个对象
before_validation
after_validation
before_save
around_save
before_create
around_create
after_create
after_save
更新对象
before_validation
after_validation
before_save
around_save
before_update
around_update
after_update
after_save
销毁对象
before_destroy
around_destroy
after_destroy
导轨 2
此列表的最新版本可以在Rails 2.3 Guides中找到
创建一个对象
before_validation
before_validation_on_create
after_validation
after_validation_on_create
before_save
before_create
-
INSERT 操作
after_create
after_save
更新对象
before_validation
before_validation_on_update
after_validation
after_validation_on_update
before_save
before_update
-
UPDATE 操作
after_update
after_save
销毁对象
before_destroy
DELETE 操作
after_destroy
由于您需要首先验证reference_code,因此可以在after_validation 回调或我上面提供的列表中出现在它之后的任何回调中调用assign_reference 方法。
【解决方案2】:
导轨 5
这是一个list with all the available Active Record callbacks,按照它们在各自操作期间被调用的顺序列出:
1 创建对象
before_validation
after_validation
before_save
around_save
before_create
around_create
after_create
after_save
after_commit/after_rollback
2 更新对象
before_validation
after_validation
before_save
around_save
before_update
around_update
after_update
after_save
after_commit/after_rollback
3 销毁对象
before_destroy
around_destroy
after_destroy
after_commit/after_rollback
after_save 在创建和更新时都运行,但总是在更具体的回调 after_create 和 after_update 之后运行,无论宏调用的执行顺序如何。
before_destroy 回调应该放在 dependent: :destroy 关联之前(或使用 prepend: true 选项),以确保它们在 dependent: :destroy 删除记录之前执行。