Jak wyświetlić listę wszystkich metod obiektu w Rubim?

113

Jak wyświetlić listę wszystkich metod, do których dany obiekt ma dostęp?

Mam @current_userobiekt zdefiniowany w kontrolerze aplikacji:

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

I chcę zobaczyć, jakie metody mam dostępne w pliku widoku. W szczególności chcę zobaczyć, jakie metody :has_manyzapewnia stowarzyszenie. (Wiem, co :has_many powinienem zapewnić, ale chcę to sprawdzić.)

Sztylet
źródło
Aby wyjaśnić, chcesz wywołać metody @current_user?
Andrew Marshall,
@Dirk, witamy w stackoverflow! Pamiętaj, aby „sprawdzić” odpowiedź, która najlepiej odpowiada na Twoje pytanie. Zagłosuj również za każdą odpowiedzią na każde pytanie, które uznasz za przydatne / pomocne.
Larry K

Odpowiedzi:

211

Poniżej wymieniono metody, które ma klasa User, a których podstawowa klasa Object nie ma ...

>> 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", ...

Zauważ, że methodsjest to metoda dla klas i dla instancji klas.

Oto metody, które ma moja klasa User, które nie należą do klasy bazowej 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.

Należy zauważyć, że metody utworzone w wyniku (wielu) relacji has_many zdefiniowanych w klasie User nie znajdują się w wynikach methodswywołania.

Dodano Uwaga: has_many nie dodaje metod bezpośrednio. Zamiast tego, maszyna ActiveRecord wykorzystuje Ruby method_missingi responds_totechniki do obsługi wywołań metod w locie. W rezultacie metody nie są wymienione w methodswyniku metody.

Larry K.
źródło
2
Chociaż może to nie być kompletne, ponieważ niektóre metody są tworzone tylko wtedy, gdy wywoływana jest metoda method_missing (np. Szukacze dynamiczne)
Frederick Cheung,
jeśli spróbuję responds_to? Błąd braku metody. Uruchamiam to wewnątrz application.html.erb
Dirk,
@Dirk - być może metoda nie jest obecna ... Sugeruję, abyś zadał nowe pytanie, w którym pokażesz, jakie są twoje definicje klasy AR, a następnie zapytaj o konkretne metody, które Twoim zdaniem: has_many powinien zapewnić. Czy masz również pasujące hasło: contrib_to? Zasady używania wielkich liter i liczby mnogiej w Railsach dla AR wprowadziły wielu na manowce ...
Larry K,
@Larry. Dzięki - mogę otrzymać listę z .to_yaml. Wygląda to tak: --- -: sketches -: sketch_ids -: sketches = -: sketch_ids = -: before_add_for_sketches -: before_add_for_sketches? <wiele pominiętych> ........ jak uzyskać dostęp do tych metod? (wskazując na docenioną dokumentację :)
Dirk
W docs dla: has_many pokazuje wiele metod, które zostały dodane. Inne są nowe w późniejszych wersjach Railsów. Należą do nich „before_add_for” itd. Są to „wywołania zwrotne skojarzeń” - zobacz tę część tego dokumentu
Larry K,
9

Moduł # instance_methods

Zwraca tablicę zawierającą nazwy publicznych i chronionych metod wystąpienia w odbiorniku. W przypadku modułu są to metody publiczne i chronione; dla klasy są to metody instancji (nie pojedyncze). Bez argumentu lub z argumentem, który jest fałszywy, zwracane są metody instancji w mod, w przeciwnym razie zwracane są metody z mod i nadklasy moda.

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
źródło
6

Lub po prostu User.methods(false)zwrócić tylko metody zdefiniowane w tej klasie.

Ruto Collins
źródło
4

Możesz to zrobić

current_user.methods

Dla lepszego wpisu

puts "\n\current_user.methods : "+ current_user.methods.sort.join("\n").to_s+"\n\n"
Andreas Lyngstad
źródło
3

A co z jednym z nich?

object.methods.sort
Class.methods.sort
Michael Frederick
źródło
1

Załóżmy, że użytkownik ma_many postów:

u = User.first
u.posts.methods
u.posts.methods - Object.methods
Marek Příhoda
źródło
1

Aby wyjaśnić odpowiedź @ clyfe. Możesz uzyskać listę swoich metod instancji za pomocą następującego kodu (zakładając, że masz klasę obiektu o nazwie „Parser”):

Parser.new.methods - Object.new.methods
Jared Menard
źródło
1

Jeśli szukasz listy metod, które odpowiadają przez instancję (w twoim przypadku @current_user). Zgodnie z metodami dokumentacji ruby

Zwraca listę nazw publicznych i chronionych metod obj. Obejmuje to wszystkie metody dostępne u przodków obj. Jeśli opcjonalny parametr ma wartość false, zwraca tablicę publicznych i chronionych metod singleton obj, tablica nie będzie zawierać metod w modułach zawartych w 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.

Alternatywnie możesz również sprawdzić, czy metoda jest wywoływana na obiekcie, czy nie ?.

@current_user.respond_to?:your_method_name

Jeśli nie chcesz metod klas nadrzędnych, po prostu odejmij od nich metody klasy nadrzędnej.

@current_user.methods - @current_user.class.superclass.new.methods #methods that are available to @current_user instance.
Mukesh Kumar Gupta
źródło