简体   繁体   中英

List all methods that an object respond_to?

I have two models,

User 
Membership

The two have the following relationship with one another

user has_many :memberships

I've been trying to figure out where the build method resides, and how do i get it in a list of methods for the instance. Here is the output of the debugger that shows my delima

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

While the following is returning false, shouldnt it return true??

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

One point is that instance_methods takes an optional boolean parameter, indicating whether you want to see methods of the instances ancestors. In your case I think you want instance_methods(true) .

However, it appears that "build" is an autogenerated method, according to the documentation . Typically the autogenerated methods in ActiveRecord are implemented by overriding method_missing and handling calls to "methods" that don't actually exist. responds_to is also overridden so that the class will indicate that it responds to the correct calls. However, since those "methods" aren't actually defined, they won't show up in the instance_methods list.

Since the list of commands that a class can respond_to using method_missing is essentially infinite, I'm pretty sure there's no way to get the list. For example, an ActiveRecord model that has attributes a,b,c, and d will automatically respond to calls such as find_by_a_and_b and find_by_a_b_and_c and find_by_b_and_d and so forth, ad infinitum. There's no way to get a list of all of those possibilities.

You could try:

@user = User.first

@user.methods.grep /method_name/

However, I don't think you'll see 'build' or 'create' in a list. Most likely these methods are generated dynamically

Please note that instance_methods returns an array of String or Symbol depending on the Ruby version.

Ruby 1.8 returns an Array of String, Ruby 1.9 an Array of Symbol.

In Ruby 1.8

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

In Ruby 1.9

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

Also, instance_methods must be called on the class, not on the instance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM