Как перечислить все методы для объекта в Ruby?

113

Как мне перечислить все методы, к которым имеет доступ конкретный объект?

У меня есть @current_userобъект, определенный в контроллере приложения:

def current_user
  @current_user ||= User.find(session[:user_id]) if session[:user_id]
end

И хочу увидеть, какие методы мне доступны в файле представления. В частности, я хочу посмотреть, какие методы предоставляет :has_manyассоциация. (Я знаю, что :has_many нужно предоставить, но хочу это проверить.)

кортик
источник
Чтобы уточнить, вы хотите, чтобы методы вызывались @current_user?
Эндрю Маршалл
@Dirk, добро пожаловать в stackoverflow! Не забудьте «проверить» ответ, который лучше всего отвечает на ваш вопрос. Также проголосуйте за любой ответ, на любой вопрос, который вы считаете полезным / полезным.
Ларри К.

Ответы:

211

Ниже будут перечислены методы, которые есть у класса User, которых нет в базовом классе Object ...

>> User.methods - Object.methods
=> ["field_types", "maximum", "create!", "active_connections", "to_dropdown",
    "content_columns", "su_pw?", "default_timezone", "encode_quoted_value", 
    "reloadable?", "update", "reset_sequence_name", "default_timezone=", 
    "validate_find_options", "find_on_conditions_without_deprecation", 
    "validates_size_of", "execute_simple_calculation", "attr_protected", 
    "reflections", "table_name_prefix", ...

Обратите внимание, что methodsэто метод для классов и для экземпляров класса.

Вот методы моего класса User, которых нет в базовом классе ActiveRecord:

>> User.methods - ActiveRecord::Base.methods
=> ["field_types", "su_pw?", "set_login_attr", "create_user_and_conf_user", 
    "original_table_name", "field_type", "authenticate", "set_default_order",
    "id_name?", "id_name_column", "original_locking_column", "default_order",
    "subclass_associations",  ... 
# I ran the statements in the console.

Обратите внимание, что методы, созданные в результате (многих) отношений has_many, определенных в классе User, не входят в результаты methodsвызова.

Добавлено Примечание: has_many не добавляет методы напрямую. Вместо этого механизм ActiveRecord использует Ruby method_missingи responds_toметоды для обработки вызовов методов на лету. В результате методы не отображаются в methodsрезультатах метода.

Ларри К.
источник
2
Хотя это может быть неполным, поскольку некоторые методы создаются только при вызове method_missing (например, динамические поисковые системы)
Фредерик Чунг
если я попробую Responds_to? Я получаю сообщение об ошибке метода. Я запускаю это внутри application.html.erb
Дирк
@Dirk - возможно, метода нет ... Я предлагаю вам задать новый вопрос, в котором вы покажете, каковы ваши определения класса AR, а затем спросите о конкретных методах, которые, по вашему мнению, должен предоставить has_many. Также есть ли у вас соответствие: own_to? Правила использования заглавных букв и плюрализации Rails для AR сбили с толку многих ...
Ларри К.
@ Ларри. Спасибо - я могу получить список с помощью .to_yaml. Это выглядит так: --- -: эскизы -: sketch_ids -: sketches = -: sketch_ids = -: before_add_for_sketches -: before_add_for_sketches? <многие пропущены> ........ как мне получить доступ к этим методам? (указывая на документацию, которая тоже приветствуется :)
Дирк
В документации для: has_many показано множество добавленных методов. Другие являются новыми для более поздних версий Rails. К ним относятся «before_add_for» и т. Д. Это «обратные вызовы ассоциации» - см. Эту часть этого документа
Ларри К.
9

Модуль # instance_methods

Возвращает массив, содержащий имена методов общедоступного и защищенного экземпляра в получателе. Для модуля это общедоступные и защищенные методы; для класса это методы экземпляра (а не одиночные). Без аргумента или с аргументом, который является ложным, возвращаются методы экземпляра в mod, в противном случае возвращаются методы в mod и суперклассах мода.

module A
  def method1()  end
end
class B
  def method2()  end
end
class C < B
  def method3()  end
end

A.instance_methods                #=> [:method1]
B.instance_methods(false)         #=> [:method2]
C.instance_methods(false)         #=> [:method3]
C.instance_methods(true).length   #=> 43
clyfe
источник
6

Или просто User.methods(false)вернуть только методы, определенные в этом классе.

Руто Коллинз
источник
4

Ты можешь сделать

current_user.methods

Для лучшего листинга

puts "\n\current_user.methods : "+ current_user.methods.sort.join("\n").to_s+"\n\n"
Андреас Люнгстад
источник
3

Что насчет одного из них?

object.methods.sort
Class.methods.sort
Майкл Фредерик
источник
1

Предположим, у пользователя есть_many сообщений:

u = User.first
u.posts.methods
u.posts.methods - Object.methods
Марек Пржихода
источник
1

Изложить ответ @clyfe. Вы можете получить список ваших методов экземпляра, используя следующий код (при условии, что у вас есть объектный класс с именем «Parser»):

Parser.new.methods - Object.new.methods
Джаред Менард
источник
1

Если вы ищете список методов, которые отвечают экземпляром (в вашем случае @current_user). Согласно методам документации ruby

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

@current_user.methods
@current_user.methods(false) #only public and protected singleton methods and also array will not include methods in modules included in @current_user class or parent of it.

Кроме того, вы также можете проверить, вызывается ли метод для объекта или нет ?.

@current_user.respond_to?:your_method_name

Если вам не нужны методы родительского класса, просто вычтите из него методы родительского класса.

@current_user.methods - @current_user.class.superclass.new.methods #methods that are available to @current_user instance.
Мукеш Кумар Гупта
источник