4

我一直在查看 ActiveRecord 源以了解:if => proc_or_method_nameActiveRecord 验证的工作原理,但源中唯一的实例:if是在解释如何调用该功能的注释中。

例如,您可以在模型中有如下一行:

validates_presence_of :name, :if => :nameable?

nameable?并且只有在方法返回给定模型的真实值时才会检查验证。

这个功能实际定义在哪里,因为我在(Rails2)源中的任何地方都找不到这种行为?

4

2 回答 2

3

从 Rails 3 开始,ActiveRecord 回调定义在active_record/callbacks.rb中,但是因为 ActiveRecord 模型继承自 ActiveModel,所以您还应该查看active_model/callbacks.rb文件。

回调功能本身是一个单独的组件。事实上,ActionController before/after 过滤器实际上是回调。出于这个原因,回调系统是一个定义在ActiveSupport::Callbacks中的模块。

将这 3 个部分完全合并,您将获得 ActiveRecord 回调功能。

于 2010-12-22T12:32:46.877 回答
3

在文件中检查了该:if选项activesupport\lib\active_support\callbacks.rb

调用该方法should_run_callback以检查是否应执行回调。

还要看看回调链是如何处理的,从run_callbacks同一个文件中的方法开始。

该文件的 v2.3.8 中的一些代码是:

def should_run_callback?(*args)
  [options[:if]].flatten.compact.all? { |a| evaluate_method(a, *args) } &&
  ![options[:unless]].flatten.compact.any? { |a| evaluate_method(a, *args) }
end

这是我发现的(以防有人感兴趣):

  1. 从 github 下载 Rails v2.3.8 并解压。
  2. :if在所有 .rb 文件中进行了 grepp
  3. 在 aactiverecord/CHANGELOG中,有一条评论提到:
    向所有验证添加了 :if 选项,这些验证可以使用块或方法指针来确定是否应该运行验证。#1324 [杜安·约翰逊/jhosteny]。
  4. 谷歌的评论。在谷歌缓存中找到它。
  5. 发现评论/添加是由 david 于 05/21/05 10:57:18 发表的
  6. 位于第 546 页上的 rails github 历史上的日期 2005-05-21 :
  7. :if对工作原理有所了解
  8. 发现commit引用的代码在v2.3.8中已经不存在了。必须找到该代码的最新位置
  9. 再次grepp'ed:if并检查每个感觉“好”的文件。来到activesupport/lib/active_support/callbacks.rb
  10. 在文件中搜索:if,它仅在方法中的一个位置找到should_run_callback
  11. 发布答案
  12. 交叉手指,等待赏金。:D

那很有趣!

于 2011-01-05T16:38:32.577 回答