before_save在验证后运行吗?

Mon*_*nti 10 ruby testing validation rspec ruby-on-rails

我的自定义验证似乎在我的before_save块之前运行,这对我来说很奇怪.我知道before_validation,但我正在尝试测试我的自定义验证器,所以before_validation钩子不允许我这样做.我还读到测试私有方法(我的验证器)是不好的做法.我该怎么办?

更多信息:我们希望用户能够使用URL或文件上载文档,但不能同时上传或不上传(xor).我的验证器检查这些的xor.如果用户编辑文档,则before_save挂钩将删除当前URL或文件.从理论上讲,流程应该是:

  1. 上传文件
  2. 验证并保存
  3. 上传网址
  4. before_save,验证,保存

但在我的测试中,我得到验证错误,表明before_save没有发生.

Sha*_*med 32

after_initialize ? (1)
Run Code Online (Sandbox Code Playgroud)
before_validation ? (2)
after_validation ? (3)
Run Code Online (Sandbox Code Playgroud)
before_save ? (4) 
Run Code Online (Sandbox Code Playgroud)
before_create ? (5)
after_create ? (6)
Run Code Online (Sandbox Code Playgroud)
after_save ? (7)
Run Code Online (Sandbox Code Playgroud)
after_commit ? (8)
Run Code Online (Sandbox Code Playgroud)


Cyb*_*Mew 6

根据https://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html,从 Ruby on 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由查找器找到并实例化的每个对象,都会触发 and 回调,并且after_initialize在实例化新对象后也会触发回调。

总共有 19 个回调,它们为您提供了巨大的能力来对 Active Record 生命周期中的每个状态做出反应和准备。为现有记录调用 ActiveRecord::Base#save 的顺序类似,只是每个_create回调都被相应的回调替换_update