Blog icon

Creating custom helper methods for the Rails console

By Glen Crawford,
Glen Crawford
Scroll down to read

When working in the Rails console, I tend to build up commands over time that I run often. These might be for resetting data, fetching something from an API, generating tokens, etc. Multiple times a day, I find myself holding down the up arrow on the keyboard until I find the last time I ran it, so I can run it again. Usually, there will be multiple commands that need to be run in sequence, which get concatenated together with semi-colons so they can all be run in one go. I don't know for sure, but I imagine every developer does this.

Example scenario

As an example, right now I'm working on a project that calls a large number of API endpoints on various different microservices. These all require authentication via a JWT token. We use Her (an ORM for making requests to REST APIs and representing their responses with Ruby classes and objects). We have some Faraday middleware that adds the JWT token (stored in RequestLocals) to the Authorization header to authenticate the requests with the microservices. This means that when I am testing these API calls in the Rails console, I need to fetch a JWT and store it in RequestLocals.

That means running this same command a few dozen times throughout each day, and holding down the up arrow on my keyboard to find it each time:

RequestLocals.store[:jwt] = JWT.create(user_id: 'USER_ID_HERE').jwt

After a while, I got tired of doing this and started looking for a better way. I wondered if I could add global helper methods to the Rails console to perform common tasks. Turns out that you can!

Implementation

First, open up config/application.rb and add this:

module MyRailsApp
  class Application < Rails::Application
    # Add custom global helper methods to the console.
    console do
      # Use this if you use IRB (the default Rails console).
      Rails::ConsoleMethods.include(ConsoleMethods)

      # Use this if you use Pry.
      # See https://blog.nhocki.com/2015/06/03/add-helper-methods-to-your-rails-console-with-pry/ for more information.
      TOPLEVEL_BINDING.eval('self').extend(ConsoleMethods)
    end
  end
end

Then create a new file called app/lib/console_methods.rb and add your method. Here's my method for the JWT scenario as an example, although obviously, you can place any method that you want here:

module ConsoleMethods
  def load_jwt!
    token = ::JWT.create(user_id: 'USER_ID_HERE')
    RequestLocals.store[:jwt] = token.jwt
  end
end

Restart your console and now you can run load_jwt! almost as if it were a built-in Rails console command/method, similar to reload!.

Note regarding reloading:

It is possible that you might find your custom commands not working after running reload!, and see an error along these lines:

ArgumentError: A copy of ConsoleMethods has been removed from the module tree but is still active!
from /Users/glen/.rvm/gems/ruby-2.4.3@acuit-nexthub-ui/gems/activesupport-5.1.3/lib/active_support/dependencies.rb:495:in `load_missing_constant'

In a future post we will dive deeper into how Rails automatically loads and reloads constants (e.g. classes), as that is complex enough to require its own post. In the meantime, simply prepend :: to the constant that you're referencing (e.g. ::User instead of User).

It's a small thing, but adding these custom methods to the console has cut out a lot of repetition from my days. Reducing some of those longer lines that I run often to just invoking a method has already saved me a lot of time. If you have any of these lines that you find and run often in the console, then this trick should improve your productivity as it did for me.

To find out how reinteractive can turn your web application vision into reality, get in touch with us through our contact form or call us on +61 2 8019 7252.