Список всех методов, которые объект отвечает_to?
У меня две модели,
User
Membership
Оба имеют следующее отношение друг к другу
user has_many :memberships
Я пытался выяснить, где находится метод сборки, и как я могу получить его в списке методов для экземпляра. Вот вывод отладчика, который показывает мою delima
(rdb:63) @user.memberships.respond_to?"build"
true
В то время как следующее возвращает false, не должно ли оно возвращать true??
(rdb:63) @user.memberships.instance_methods.include?"build"
false
Ответы
Ответ 1
Одно дело, что instance_methods
принимает необязательный логический параметр, указывающий, хотите ли вы видеть методы предков-экземпляров. В вашем случае я думаю, что вы хотите instance_methods(true)
.
Однако, похоже, что "сборка" - это автогенерированный метод, согласно документации. Как правило, автогенерируемые методы в 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
и т.д., До бесконечности. Невозможно получить список всех этих возможностей.
Ответ 2
Обратите внимание, что instance_methods
возвращает массив String или Symbol в зависимости от версии Ruby.
Ruby 1.8 возвращает массив строк, Ruby 1.9 - Array of Symbol.
В Ruby 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
должен быть вызван в классе, а не в экземпляре.
Ответ 3
Вы можете попробовать:
@user = User.first
@user.methods.grep /method_name/
Однако я не думаю, что вы увидите "build" или "create" в списке. Скорее всего, эти методы генерируются динамически