Search code examples
ruby-on-railsrubyintrospection

How do I find the Rails module path for a method


New to ruby/rails. In a big Rails app, I come across methods and can't find the documentation for them. For example, there is a method process. When I introspect and examine its ancestors, I can get to Rails::Controller::Testing::TemplateAssertions.process but googling that doesn't give me any documentation about how to use the method, just the method's definition which is very obscure.

What I wanted to find was ActionDispatch::Integration::Session.process which I can then look up in https://api.rubyonrails.org/ and get verbose documentation on how to use the method. I think I have trouble finding this "original" module path because of Rails's use of mixins. The only way I found it was by sifting through files and files of the rails repository before I found it mentioned in some comment. So my question is, is there a more deterministic way to find the origin of a method?

EDIT: the context of this code looks kind of like this:

require 'test_helper'
class C < ActionDispatch::IntegrationTest
   include OtherHelper
   ...
   process(argA,argB,argC)
end

Solution

  • There are a couple things you can use to help with introspection & debugging:

    • Installing & requiring pry, pry-byebug and placing a binding.pry somewhere in the code will allow you to step/next thru the logic until you get to where you think you need to be
    • Using the owner method as noted in the comment to your post. If you have a User model, you can, for example, from a console type User.method(:_update_callbacks).owner and see that it's from ActiveRecord::Base
    • You can use the .source_location method to see which file something is defined in. For example, from a rails console I can type User.method(:_update_callbacks).source_location and see that method is defined on line 819 of the active_support/callbacks.rb file (with the full path noted in the response)
    • If you knew that the module was being included, but weren't able to figure out where you could also edit the gem on your local system to print where it's being included

    The below prints out Bar

    module Foo
      def self.included(base)
        puts "including..."
        puts base
        puts "included..."
      end
    end
    
    class Bar
      include Foo
    end
    

    There's probably something better/cleaner out there but these might be useful.

    More detail on using pry, per my comment below:

    Given that I've run gem install pry pry-byebug and have the following code sample:

    require 'pry'
    require 'pry-byebug'
    
    module Foo
      def blah
        puts "in Foo"
      end
    end
    
    class Bar
      include Foo
    
      def blah
        binding.pry
        super
        puts "in Bar"
      end
    end
    
    x = Bar.new
    x.blah
    

    When you hit the binding.pry, before the super, you can call next and that will step you into the new file where you can see file name and line number. You'll need to add the binding.pry in the actual gem file on your machine. bundle open <gemname> or gem open <gemname> should open the actual folder in your editor, and as long as you've got pry/byebug configured in your Gemfile (if using bundler) or install via gem, it should work.

    step with pry