2010-12-22 48 views
4

我一直在瀏覽ActiveRecord源代碼,以瞭解:if => proc_or_method_name如何在ActiveRecord驗證中工作,但源代碼中僅有:if的實例在註釋中解釋如何調用該功能。ActiveRecord如何在驗證中實現`:if => ...`

例如,你可以像在模型下面的一行:

validates_presence_of :name, :if => :nameable? 

和驗證只有在nameable?方法返回給定的模型truthy值被檢查。

這個功能在哪裏實際定義,因爲我無法在(Rails2)源代碼中的任何位置找到此行爲?

回答

3

在文件activesupport\lib\active_support\callbacks.rb中檢查:if選項。

方法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 

這裏是我怎麼發現的(如果有人有興趣):從GitHub

  1. 下載的Rails v2.3.8並解壓縮它。
  2. 在所有的.rb文件grepp'ed爲:if
  3. activerecord/CHANGELOG,位於該提到的評論:
    添加了:如果選項的所有驗證是可以使用一個塊或方法指針以確定是否驗證應該運行或不運行。 #1324 [Duane Johnson/jhosteny]。
  4. Google對該評論。發現它在google cache
  5. 發現這個評論/除了由大衛
  6. 位於日期2005-05-21在05年5月21日10時57分18秒取得的rails github history on page 546
  7. 得到的:if如何工作
  8. 端倪
  9. 發現引用的代碼在v2.3.8中不再存在。必須找到該代碼的最新位置
  10. 再次grepp'ed :if並通過每個感覺「好」的文件。來到activesupport/lib/active_support/callbacks.rb
  11. 在該文件中搜索了:if,並且在方法should_run_callback中僅在一個位置發現了它。
  12. 已發佈的問題回答
  13. 交叉手指並等待賞金。 :D

這很有趣!

3

從Rails 3開始,ActiveRecord回調在active_record/callbacks.rb中定義,但由於ActiveRecord模型繼承自ActiveModel,因此您還應該查看active_model/callbacks.rb文件。

回調功能本身是一個獨立的組件。實際上,ActionController之前/之後的過濾器實際上是回調。 因此,回調系統是ActiveSupport::Callbacks中定義的模塊。

將這3個部分完全合併,即可獲得ActiveRecord回調功能。

+0

對不起,花了這麼長的時間回覆。我的意思是Rails2,但除了分離到ActiveModel之外,我認爲這不是一個問題。我用更多的信息更新了這個問題,因爲我給了我錯誤的印象。 – Gareth 2011-01-05 11:53:53