Как ActiveRecord реализует `: if => ...` для проверок - PullRequest
4 голосов
/ 22 декабря 2010

Я просматривал источник ActiveRecord, чтобы выяснить, как :if => proc_or_method_name работает с проверками ActiveRecord, но единственные экземпляры :if в источнике находятся в комментариях, объясняющих, как следует вызывать эту функцию.

Например, в модели может быть строка, подобная следующей:

validates_presence_of :name, :if => :nameable?

, и проверка будет проверена только в том случае, если метод nameable? возвращает истинное значение для данной модели.

Где на самом деле определена эта функциональность, поскольку я не могу найти такое поведение нигде в источнике (Rails2)?

Ответы [ 2 ]

3 голосов
/ 05 января 2011

Параметр :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. Скачал Rails v2.3.8 с github и распаковал его.
  2. grepp'ed для :if во всех файлах .rb
  3. В activerecord/CHANGELOG находится комментарий, в котором упоминается:
    Добавлена ​​опция: if для всех проверок, которые могут использовать либо блок, либо указатель на метод, чтобы определить, следует ли выполнять проверку или нет. # 1324 [Дуэйн Джонсон / Джостени].
  4. Google за этот комментарий. Нашел его в гугле кеше .
  5. Обнаружено, что комментарий / дополнение было сделано 21.05.05 10:57:18 Дэвидом
  6. Дата размещения 2005-05-21 в rails github history на стр. 546 :
  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

Это было весело!

3 голосов
/ 22 декабря 2010

Начиная с Rails 3, обратные вызовы ActiveRecord определены в active_record / callbacks.rb , но поскольку модель ActiveRecord наследуется от ActiveModel, вам также следует взглянуть на active_model / callbacks.rb файл.

Функция обратного вызова сама по себе является отдельным компонентом.Фактически, ActionController до / после фильтров - это обратные вызовы.По этой причине система обратного вызова - это модуль, определенный в ActiveSupport :: Callbacks .

. Объедините все эти 3 части, и вы получите функцию обратных вызовов ActiveRecord.

...