149

How do I list all the methods that a particular object has access to?

I have a @current_user object, defined in the application controller:

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

And want to see what methods I have available to me in the view file. Specifically, I want to see what methods a :has_many association provides. (I know what :has_many should provide, but want to check that.)

halfer
  • 19,824
  • 17
  • 99
  • 186
Dirk
  • 3,073
  • 4
  • 31
  • 36

8 Answers8

270

The following will list the methods that the User class has that the base Object class does not have...

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

Note that methods is a method for Classes and for Class instances.

Here's the methods that my User class has that are not in the ActiveRecord base class:

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

Note that the methods created as a result of the (many) has_many relationships defined in the User class are not in the results of the methods call.

Added Note that :has_many does not add methods directly. Instead, the ActiveRecord machinery uses the Ruby method_missing and responds_to techniques to handle method calls on the fly. As a result, the methods are not listed in the methods method result.

Larry K
  • 47,808
  • 15
  • 87
  • 140
  • 2
    Although that may not be complete since some methods are only created when method_missing is called (eg dynamic finders) – Frederick Cheung Dec 21 '11 at 19:36
  • if I try responds_to? I get a method missing error. I'm running this inside application.html.erb – Dirk Dec 21 '11 at 19:48
  • @Dirk -- maybe the method is not present...I suggest you file a new question where you show what your AR Class definitions are and then ask about the specific methods that you think :has_many should provide. Also do you have the matching :belongs_to? Rails's capitalization and pluralization rules for AR have led many astray... – Larry K Dec 21 '11 at 19:56
  • @Larry. Thanks - I can get a list with .to_yaml. It looks like this: --- - :sketches - :sketch_ids - :sketches= - :sketch_ids= - :before_add_for_sketches - :before_add_for_sketches? ........how do I access those methods? (pointing me to documentation appreciated too :) – Dirk Dec 21 '11 at 20:12
  • The [docs](http://guides.rubyonrails.org/association_basics.html#has_many-association-reference) for :has_many shows many of the methods that are added. Others are new for later versions of Rails. These include the "before_add_for" etc. They are "Association Callbacks" -- see that part of this [doc](http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html) – Larry K Dec 21 '11 at 20:21
  • Thank you – Dirk Dec 21 '11 at 20:25
  • I like to add a (.sort) on the end to see alphabetized results array (User.methods.sort - Object.methods) – user847074 Jan 31 '18 at 06:38
  • Do this ```methods = (User.methods - Object.methods)``` to put it into an array and then you can do ```methods.include?("method_name")``` – zasman Aug 21 '18 at 14:02
  • @LarryK Hi, is there any shortcut way to list methods added by specific gem on any object any ? – codemilan Nov 19 '19 at 05:01
  • Try getting the method list before and after adding the specific gem to see what changed – Larry K Nov 19 '19 at 13:26
39

Or just User.methods(false) to return only the methods defined within that class.

Kaka Ruto
  • 4,581
  • 1
  • 31
  • 39
14

Module#instance_methods

Returns an array containing the names of the public and protected instance methods in the receiver. For a module, these are the public and protected methods; for a class, they are the instance (not singleton) methods. With no argument, or with an argument that is false, the instance methods in mod are returned, otherwise the methods in mod and mod’s superclasses are returned.

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
  • 23,695
  • 8
  • 85
  • 109
7

You can do

current_user.methods

For better listing

puts "\n\current_user.methods : "+ current_user.methods.sort.join("\n").to_s+"\n\n"
Andreas Lyngstad
  • 4,887
  • 2
  • 36
  • 69
4

If You are looking list of methods which respond by an instance (in your case @current_user). According to ruby documentation methods

Returns a list of the names of public and protected methods of obj. This will include all the methods accessible in obj's ancestors. If the optional parameter is false, it returns an array of obj's public and protected singleton methods, the array will not include methods in modules included 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.

Alternatively, You can also check that a method is callable on an object or not?.

@current_user.respond_to?:your_method_name

If you don't want parent class methods then just subtract the parent class methods from it.

@current_user.methods - @current_user.class.superclass.new.methods #methods that are available to @current_user instance.
Mukesh Kumar Gupta
  • 1,567
  • 20
  • 15
4

What about one of these?

object.methods.sort
Class.methods.sort
Michael Frederick
  • 16,664
  • 3
  • 43
  • 58
1

To expound upon @clyfe's answer. You can get a list of your instance methods using the following code (assuming that you have an Object Class named "Parser"):

Parser.new.methods - Object.new.methods
Jared Menard
  • 2,654
  • 1
  • 21
  • 22
1

Suppose User has_many Posts:

u = User.first
u.posts.methods
u.posts.methods - Object.methods
Marek Příhoda
  • 11,108
  • 3
  • 39
  • 53