Перечислите все методы, которые объект response_to? - PullRequest
15 голосов
/ 13 апреля 2011

У меня две модели,

User 
Membership

Они имеют следующие отношения друг с другом

user has_many :memberships

Я пытался выяснить, где находится метод сборки, и как я могу получить его в списке методов для экземпляра. Вот вывод отладчика, который показывает мою гастрономию

(rdb:63) @user.memberships.respond_to?"build"
true

Пока следующее возвращает false, не должно ли оно вернуть true ??

(rdb:63) @user.memberships.instance_methods.include?"build"
false

Ответы [ 3 ]

9 голосов
/ 13 апреля 2011

Одно замечание: instance_methods принимает необязательный логический параметр, указывающий, хотите ли вы видеть методы предков экземпляров. В вашем случае я думаю, что вы хотите instance_methods(true).

Однако, похоже, что "build" - это автоматически сгенерированный метод, согласно документации . Обычно автоматически генерируемые методы в ActiveRecord реализуются путем переопределения method_missing и обработки вызовов «методов», которые на самом деле не существуют. responds_to также переопределяется, так что класс будет указывать, что он отвечает на правильные вызовы. Однако, поскольку эти «методы» на самом деле не определены, они не будут отображаться в списке instance_methods.

Поскольку список команд, которые класс может respond_to использовать method_missing, по существу бесконечен, я почти уверен, что нет способа получить этот список. Например, модель ActiveRecord, имеющая атрибуты a, b, c и d, будет автоматически отвечать на вызовы, такие как find_by_a_and_b и find_by_a_b_and_c и find_by_b_and_d и т. Д., До бесконечности. Нет способа получить список всех этих возможностей.

5 голосов
/ 13 апреля 2011

Обратите внимание, что instance_methods возвращает массив строк или символов в зависимости от версии Ruby.

Ruby 1.8 возвращает массив строк, Ruby 1.9 - массив символов.

InRuby 1.8

"".respond_to?(:upcase)
# => true 
"".class.instance_methods.include?("upcase")
# => false
"".class.instance_methods.include?(:upcase)
# => false

В Ruby 1.9

"".respond_to?(:upcase)
# => true 
"".class.instance_methods.include?("upcase")
# => false
"".class.instance_methods.include?(:upcase)
# => true

Кроме того, instance_methods должен вызываться для класса, а не для экземпляра.

5 голосов
/ 13 апреля 2011

Вы можете попробовать:

@user = User.first

@user.methods.grep /method_name/

Однако я не думаю, что вы увидите «build» или «create» в списке. Скорее всего, эти методы генерируются динамически

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...