Ruby on Rails: как узнать, где вызывается метод?

Я быстро разбираюсь в существующем проекте Rails, и мне интересно, где изменяется конкретный атрибут (поле) в модели (ActiveRecord). В Java я бы либо использовал функцию Eclipse «найти ссылку» в установщике, либо установил там точку останова. В ActiveRecord этот атрибут даже не указан в файле класса! Конечно, я могу выполнять текстовый поиск и просматривать сотни результатов, но это не соответствует смыслу работы с IDE. Есть ли способ лучше? Я использую РубиМайн.


person Dmitry Chornyi    schedule 30.09.2011    source источник


Ответы (2)


tl;dr

Kernel.caller

Объяснение

Rails использует method_missing для реализации методов атрибутов в моделях ActiveRecord. Вы можете увидеть это в исходном коде ActiveRecord::Base. code. Я бы подошел к этой проблеме для класса модели YourModel так:

class YourModel < ActiveRecord::Base
  def myfield=(*args)
    Rails.logger.debug "myfield called at #{Kernel.caller.inspect}"
    super(*args)
  end
end

На самом деле есть несколько других способов обновления вашего атрибута, например update_attribute и friends. Если вы не можете найти сайт вызова назначения, вы можете продолжать переопределять методы, пока не найдете тот, который использует ваш код. В качестве альтернативы вы можете изменить ActiveRecord::Base в своей локальной копии гема ("bundle show activerecord" указывает путь к нему).

person Spike Gronim    schedule 30.09.2011
comment
У меня нет опыта работы с АР. Я использую монгоид. Но я предполагаю, что даже функции массового назначения, такие как update_attributes, в конечном итоге будут проходить через отдельные установщики полей, по крайней мере, в Mongoid. Так что это решение будет работать и для массовых заданий. - person brahmana; 01.10.2011

RubyMine имеет справочную функцию поиска, такую ​​​​как eclipse. Однако это не сильно поможет при навигации по исходному коду Rails, поскольку AR использует много метапрограммирования. При просмотре результатов поиска вы захотите посмотреть на строки, которые используют «отправить», а также на простые вызовы вашей функции.

Еще одна вещь, о которой вам нужно знать, это то, что AR синтезирует код во время выполнения; метод, который вы ищете, может даже не присутствовать в исходном коде.

person Jeff Paquette    schedule 30.09.2011