2011-04-13 21 views
15

Tengo dos modelos,¿Listar todos los métodos que responde un objeto?

User 
Membership 

Los dos han la siguiente relación entre sí

user has_many :memberships 

He estado tratando de averiguar dónde reside el método de aumento, y cómo lo consigo en una lista de métodos para la instancia. Aquí está la salida del depurador que muestra mi Delima

(rdb:63) @user.memberships.respond_to?"build" 
true 

Aunque la siguiente regresa falso, no debería devolverlo cierto ??

(rdb:63) @user.memberships.instance_methods.include?"build" 
false 
+0

no podrá ver 'compilación' en una lista, probablemente se esté generando usando 'method_missing' –

+0

¿Hay algún modo de que inspeccioné la implementación de method_missing para esto? Quiero llegar a la raíz de cómo funciona esto –

+0

sí, intente ejecutar esto: User.new.memberships.method_missing (: build) Debería ver la excepción diciendo que se llamó al método protegido 'build', entonces puedes intentar seguirlo.Pero eso necesitaría algo de tiempo –

Respuesta

9

Un punto es que instance_methods toma un parámetro booleano opcional, indicando si desea ver los métodos de los antepasados ​​de los casos. En tu caso, creo que quieres instance_methods(true).

Sin embargo, parece que "compilar" es un método autogenerado, según the documentation. Normalmente, los métodos autogenerados en ActiveRecord se implementan anulando method_missing y manejando llamadas a "métodos" que en realidad no existen. responds_to también se anula para que la clase indique que responde a las llamadas correctas. Sin embargo, dado que esos "métodos" en realidad no están definidos, no aparecerán en la lista instance_methods.

Dado que la lista de comandos que una clase puede respond_to usando method_missing es esencialmente infinita, estoy bastante seguro de que no hay forma de obtener la lista. Por ejemplo, un modelo de ActiveRecord que tenga los atributos a, b, cyd responderá automáticamente a llamadas como find_by_a_and_b y find_by_a_b_and_c y find_by_b_and_d y así sucesivamente, ad infinitum. No hay forma de obtener una lista de todas esas posibilidades.

+0

No funcionó. Salida adjunta (también intenté invocarla en la clase en lugar de la instancia por sugerencia de Simone) (rdb: 63) @ user.memberships.class.instance_methods (true) .include? "Build" false (rdb: 63) @ user.memberships.instance_methods (true) .include? "build" false –

5

Usted podría intentar:

@user = User.first 

@user.methods.grep /method_name/ 

Sin embargo, no creo que usted verá 'construir' o 'crear' en una lista. Lo más probable es que estos métodos se generen dinámicamente

5

Tenga en cuenta que instance_methods devuelve una matriz de Cadena o Símbolo según la versión de Ruby.

Ruby 1.8 devuelve una matriz de cadenas, Ruby 1.9 y una matriz de símbolos.

en Ruby 1,8

"".respond_to?(:upcase) 
# => true 
"".class.instance_methods.include?("upcase") 
# => false 
"".class.instance_methods.include?(:upcase) 
# => false 

en Ruby 1,9

"".respond_to?(:upcase) 
# => true 
"".class.instance_methods.include?("upcase") 
# => false 
"".class.instance_methods.include?(:upcase) 
# => true 

También, instance_methods debe ser llamado en la clase, no en la instancia.

+0

Didnt work (rdb: 63) @ user.memberships.instance_methods (true) .include? (: build) false (rdb: 63) @user .memberships.class.instance_methods (true) .include? (: build) false –

Cuestiones relacionadas