Wie liste ich alle Methoden für ein Objekt in Ruby auf?

112

Wie liste ich alle Methoden auf, auf die ein bestimmtes Objekt Zugriff hat?

Ich habe ein @current_userObjekt, das im Anwendungscontroller definiert ist:

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

Und möchten sehen, welche Methoden mir in der Ansichtsdatei zur Verfügung stehen. Insbesondere möchte ich sehen, welche Methoden eine :has_manyZuordnung bereitstellt. (Ich weiß, was :has_many zu bieten ist, möchte das aber überprüfen.)

Dolch
quelle
Zur Verdeutlichung möchten Sie die Methoden aufrufen @current_user?
Andrew Marshall
@Dirk, willkommen bei stackoverflow! Denken Sie daran, die Antwort zu "überprüfen", die Ihre Frage am besten beantwortet. Stimmen Sie auch jede Antwort auf jede Frage ab, die Sie nützlich / hilfreich finden.
Larry K

Antworten:

209

Im Folgenden werden die Methoden aufgelistet, über die die Benutzerklasse verfügt, die die Basisobjektklasse nicht hat ...

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

Beachten Sie, dass dies methodseine Methode für Klassen und für Klasseninstanzen ist.

Hier sind die Methoden meiner Benutzerklasse, die nicht zur ActiveRecord-Basisklasse gehören:

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

Beachten Sie, dass die Methoden, die als Ergebnis der (vielen) has_many-Beziehungen erstellt wurden, die in der User-Klasse definiert sind, nicht in den Ergebnissen des methodsAufrufs enthalten sind.

Hinzugefügt Beachten Sie Folgendes: has_many fügt keine Methoden direkt hinzu. Stattdessen verwendet die ActiveRecord-Maschinerie Ruby method_missingund responds_toTechniken, um Methodenaufrufe im laufenden Betrieb zu verarbeiten. Infolgedessen werden die Methoden nicht im Methodenergebnis aufgeführt methods.

Larry K.
quelle
2
Obwohl dies möglicherweise nicht vollständig ist, da einige Methoden nur erstellt werden, wenn method_missing aufgerufen wird (z. B. dynamische Finder)
Frederick Cheung
wenn ich antworte_to? Ich bekomme eine Methode fehlenden Fehler. Ich führe dies in application.html.erb
Dirk
@Dirk - Vielleicht ist die Methode nicht vorhanden ... Ich schlage vor, dass Sie eine neue Frage stellen, in der Sie Ihre AR-Klassendefinitionen anzeigen und dann nach den spezifischen Methoden fragen, die Sie denken: has_many sollte bereitstellen. Haben Sie auch das passende: Gehört zu? Rails Kapitalisierungs- und Pluralisierungsregeln für AR haben viele in die Irre geführt ...
Larry K
@ Larry. Danke - ich kann eine Liste mit .to_yaml bekommen. Es sieht so aus: --- -: Skizzen -: Skizzen_ids -: Skizzen = -: Skizzen_ids = -: vor_add_for_sketches -: vor_add_for_sketches? <viele weggelassen> ........ wie greife ich auf diese Methoden zu? (Hinweis auf Dokumentation auch geschätzt :)
Dirk
Die Dokumentation für: has_many zeigt viele der hinzugefügten Methoden. Andere sind neu für spätere Versionen von Rails. Dazu gehören "before_add_for" usw. Sie sind "Association Callbacks" - siehe diesen Teil dieses Dokuments
Larry K
9

Modul # instance_methods

Gibt ein Array zurück, das die Namen der öffentlichen und geschützten Instanzmethoden im Empfänger enthält. Für ein Modul sind dies die öffentlichen und geschützten Methoden. Für eine Klasse sind dies die Instanzmethoden (nicht Singleton-Methoden). Ohne Argument oder mit einem Argument, das falsch ist, werden die Instanzmethoden in mod zurückgegeben, andernfalls werden die Methoden in mod und die Superklassen von mod zurückgegeben.

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
quelle
6

Oder nur User.methods(false)um nur die in dieser Klasse definierten Methoden zurückzugeben.

Ruto Collins
quelle
4

Du kannst tun

current_user.methods

Zur besseren Auflistung

puts "\n\current_user.methods : "+ current_user.methods.sort.join("\n").to_s+"\n\n"
Andreas Lyngstad
quelle
3

Was ist mit einem davon?

object.methods.sort
Class.methods.sort
Michael Frederick
quelle
1

Angenommen, der Benutzer hat_ viele Beiträge:

u = User.first
u.posts.methods
u.posts.methods - Object.methods
Marek Příhoda
quelle
1

Um die Antwort von @ clyfe zu erläutern. Mit dem folgenden Code können Sie eine Liste Ihrer Instanzmethoden abrufen (vorausgesetzt, Sie haben eine Objektklasse mit dem Namen "Parser"):

Parser.new.methods - Object.new.methods
Jared Menard
quelle
1

Wenn Sie eine Liste von Methoden suchen, die von einer Instanz antworten (in Ihrem Fall @current_user). Laut Dokumentation ruby Methoden

Gibt eine Liste der Namen öffentlicher und geschützter Methoden von obj zurück. Dies schließt alle Methoden ein, auf die die Vorfahren von obj zugreifen können. Wenn der optionale Parameter false ist, wird ein Array der öffentlichen und geschützten Singleton-Methoden von obj zurückgegeben. Das Array enthält keine Methoden in Modulen, die in obj enthalten sind.

@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.

Alternativ können Sie auch überprüfen, ob eine Methode für ein Objekt aufrufbar ist oder nicht.

@current_user.respond_to?:your_method_name

Wenn Sie keine übergeordneten Klassenmethoden möchten, subtrahieren Sie einfach die übergeordneten Klassenmethoden davon.

@current_user.methods - @current_user.class.superclass.new.methods #methods that are available to @current_user instance.
Mukesh Kumar Gupta
quelle