Come elencare tutti i metodi per un oggetto in Ruby?


113

Come si elencano tutti i metodi a cui ha accesso un particolare oggetto?

Ho un @current_useroggetto, definito nel controller dell'applicazione:

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

E voglio vedere quali metodi ho a disposizione nel file di visualizzazione. In particolare, voglio vedere quali metodi :has_manyfornisce un'associazione. (So ​​cosa :has_many dovrebbe fornire, ma voglio controllarlo.)


Per chiarire, vuoi che i metodi siano richiamabili @current_user?
Andrew Marshall

@Dirk, benvenuto in stackoverflow! Ricordati di "selezionare" la risposta che meglio risponde alla tua domanda. Vota anche qualsiasi risposta, a qualsiasi domanda, che trovi utile / utile.
Larry K

Risposte:


211

Di seguito elencherà i metodi che la classe User ha che la classe Object di base non ha ...

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

Notare che methodsè un metodo per le classi e per le istanze di classi.

Ecco i metodi della mia classe User che non sono nella classe base 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.

Notare che i metodi creati come risultato delle (molte) relazioni has_many definite nella classe User non sono nei risultati della methodschiamata.

Nota aggiunta che: has_many non aggiunge metodi direttamente. Invece, il meccanismo ActiveRecord utilizza Ruby method_missinge le responds_totecniche per gestire le chiamate ai metodi al volo. Di conseguenza, i metodi non sono elencati nel methodsrisultato del metodo.


2
Anche se ciò potrebbe non essere completo poiché alcuni metodi vengono creati solo quando viene chiamato method_missing (ad es. Cercatori dinamici)
Frederick Cheung

se provo replys_to? Ottengo un errore di metodo mancante. Lo sto eseguendo all'interno di application.html.erb
Dirk

@Dirk - forse il metodo non è presente ... ti suggerisco di presentare una nuova domanda in cui mostri quali sono le tue definizioni di classe AR e poi chiedi dei metodi specifici che pensi: has_many dovrebbe fornire. Inoltre hai la corrispondenza: appartiene_to? Le regole di capitalizzazione e pluralizzazione di Rails per AR hanno portato molti fuori strada ...
Larry K

@Larry. Grazie - posso ottenere un elenco con .to_yaml. Assomiglia a questo: --- -: sketches -: sketch_ids -: sketches = -: sketch_ids = -: before_add_for_sketches -: before_add_for_sketches? <molti omessi> ........ come accedo a questi metodi? (indicandomi anche una documentazione apprezzata :)
Dirk

La documentazione per: has_many mostra molti dei metodi aggiunti. Altri sono nuovi per le versioni successive di Rails. Questi includono "before_add_for" ecc. Sono "Callback dell'associazione" - vedi quella parte di questo documento
Larry K

9

# instance_methods modulo

Restituisce un array contenente i nomi dei metodi di istanza pubblici e protetti nel ricevitore. Per un modulo, questi sono i metodi pubblici e protetti; per una classe, sono i metodi di istanza (non singleton). Senza argomento, o con un argomento falso, vengono restituiti i metodi di istanza in mod, altrimenti vengono restituiti i metodi in mod e le superclassi di 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

6

O semplicemente User.methods(false)per restituire solo i metodi definiti all'interno di quella classe.


4

Tu puoi fare

current_user.methods

Per un elenco migliore

puts "\n\current_user.methods : "+ current_user.methods.sort.join("\n").to_s+"\n\n"


1

Supponiamo che l'utente abbia_molti post:

u = User.first
u.posts.methods
u.posts.methods - Object.methods

1

Per esporre la risposta di @ clyfe. Puoi ottenere un elenco dei metodi dell'istanza utilizzando il codice seguente (supponendo che tu abbia una classe di oggetti denominata "Parser"):

Parser.new.methods - Object.new.methods

1

Se stai cercando un elenco di metodi che rispondono da un'istanza (nel tuo caso @current_user). Secondo i metodi di documentazione di ruby

Restituisce un elenco dei nomi dei metodi pubblici e protetti di obj. Ciò includerà tutti i metodi accessibili negli antenati di obj. Se il parametro facoltativo è false, restituisce un array di metodi singleton pubblici e protetti di obj, l'array non includerà metodi nei moduli inclusi in 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.

In alternativa, puoi anche verificare che un metodo sia richiamabile su un oggetto oppure no ?.

@current_user.respond_to?:your_method_name

Se non vuoi metodi della classe genitore, sottrai semplicemente i metodi della classe genitore da esso.

@current_user.methods - @current_user.class.superclass.new.methods #methods that are available to @current_user instance.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.