验证后 before_save 运行 吗?
Does before_save run after validations?
我的自定义验证似乎 运行 在我的 before_save
块之前,这对我来说很奇怪。我知道 before_validation
,但我正在尝试测试我的自定义验证器,因此 before_validation 挂钩不允许我这样做。我还读到测试私有方法(我的验证器)是不好的做法。我该怎么办?
更多信息:我们希望用户能够上传带有 URL 或文件的文档,但不能同时上传或 none (xor)。我的验证器检查这些的异或。如果用户编辑文档,before_save
挂钩会删除当前的 URL 或文件。理论上流量应该是:
- 上传文件
- 验证并保存
- 上传URL
- before_save、验证、保存
但在我的测试中,我收到验证错误,表明 before_save
没有发生。
after_initialize ↓ (1)
before_validation ↓ (2)
after_validation ↓ (3)
before_save ↓ (4)
before_create ↓ (5)
after_create ↓ (6)
after_save ↓ (7)
after_commit ↓ (8)
根据 https://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html,从 Ruby 到 Rails 5.2.0:
活动记录回调
回调是 Active Record 对象生命周期的挂钩,允许您在对象状态更改之前或之后触发逻辑。这可用于确保在调用 ActiveRecord::Base#destroy 时删除关联和依赖对象(通过覆盖 before_destroy
)或在验证属性之前对其进行处理(通过覆盖 before_validation
).作为启动回调的示例,考虑对新记录的 ActiveRecord::Base#save 调用:
(-) save
(-) valid
(1) before_validation
(-) validate
(2) after_validation
(3) before_save
(4) before_create
(-) create
(5) after_create
(6) after_save
(7) after_commit
此外,可以将 after_rollback
回调配置为在发出回滚时触发。查看 ActiveRecord::Transactions 了解有关 after_commit
和 after_rollback
的更多详细信息。
此外,只要触摸对象,就会触发 after_touch
回调。
最后,为查找器找到并实例化的每个对象触发 after_find
和 after_initialize
回调,在实例化新对象后也会触发 after_initialize
。
总共有 19 个回调,它们为您提供了强大的反应能力,可以为 Active Record 生命周期中的每个状态做好准备。为现有记录调用 ActiveRecord::Base#save 的顺序类似,只是每个 _create
回调被相应的 _update
回调替换。
我的自定义验证似乎 运行 在我的 before_save
块之前,这对我来说很奇怪。我知道 before_validation
,但我正在尝试测试我的自定义验证器,因此 before_validation 挂钩不允许我这样做。我还读到测试私有方法(我的验证器)是不好的做法。我该怎么办?
更多信息:我们希望用户能够上传带有 URL 或文件的文档,但不能同时上传或 none (xor)。我的验证器检查这些的异或。如果用户编辑文档,before_save
挂钩会删除当前的 URL 或文件。理论上流量应该是:
- 上传文件
- 验证并保存
- 上传URL
- before_save、验证、保存
但在我的测试中,我收到验证错误,表明 before_save
没有发生。
after_initialize ↓ (1)
before_validation ↓ (2)
after_validation ↓ (3)
before_save ↓ (4)
before_create ↓ (5)
after_create ↓ (6)
after_save ↓ (7)
after_commit ↓ (8)
根据 https://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html,从 Ruby 到 Rails 5.2.0:
活动记录回调
回调是 Active Record 对象生命周期的挂钩,允许您在对象状态更改之前或之后触发逻辑。这可用于确保在调用 ActiveRecord::Base#destroy 时删除关联和依赖对象(通过覆盖 before_destroy
)或在验证属性之前对其进行处理(通过覆盖 before_validation
).作为启动回调的示例,考虑对新记录的 ActiveRecord::Base#save 调用:
(-)
save
(-)
valid
(1)
before_validation
(-)
validate
(2)
after_validation
(3)
before_save
(4)
before_create
(-)
create
(5)
after_create
(6)
after_save
(7)
after_commit
此外,可以将 after_rollback
回调配置为在发出回滚时触发。查看 ActiveRecord::Transactions 了解有关 after_commit
和 after_rollback
的更多详细信息。
此外,只要触摸对象,就会触发 after_touch
回调。
最后,为查找器找到并实例化的每个对象触发 after_find
和 after_initialize
回调,在实例化新对象后也会触发 after_initialize
。
总共有 19 个回调,它们为您提供了强大的反应能力,可以为 Active Record 生命周期中的每个状态做好准备。为现有记录调用 ActiveRecord::Base#save 的顺序类似,只是每个 _create
回调被相应的 _update
回调替换。