Back to blog

Useful things you can do with Rails console

Ruby

January 07, 2025

Paweł Dąbrowski

Founder / Software Engineer

Rails console is the type of tool that we, as Rails developers, heavily use in production and development environments for any type of the apps. Besides interacting with the database to read or manipulate records, there are plenty of other use cases where you can find the Rails console useful.

You can even personalize the console for the given project to increase the ease of usage and efficiency. In this article, I will present all the more and less known console features you can use to interact with the database and code in your project.

Making the work with the console more comfortable

I wouldn’t say that working with the Rails console is uncomfortable, but let me share with you a few tips that make the work even easier and more comfortable.

Silence SQL logs when executing queries

Depending on the actions that you perform on the database and the nature of your data, a lot is going on in logs when making the queries:

User.find_each(&:touch)
# User Load (0.6ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1000
# TRANSACTION (0.2ms)  BEGIN
# User Update (1.7ms)  UPDATE "users" SET …

When you use puts inside your code to monitor the progress or just debug some parts of the process, it’s easy to lose track of them among the logs. You can silence the logs by wrapping the code inside the special block:

ActiveRecord::Base.logger.silence { User.find_each(&:touch) } # => nil

From now on, the console output will be free from the SQL logs and queries.

Accessing the last returned value

Raise your hand if you never forget to assign to a variable result of some operation in the console and then you have to make it again. Thankfully we have a special variable _ that allows us to access the last result printed in the console:

3.3.6 :001 > 4 + 4
=> 8
3.3.6 :002 > _
=> 8

You can treat the floor character as an ordinary variable and use it to print something or pass it as an argument to some method.

Switching the current context with irb workspaces

If you are working with objects to which access you need to get via many chained calls, you can make your work a little bit more efficient by creating a dedicated workspace for a given object.

Given you have a User class instance that provides an address object which provides a location object which provides some useful methods:

user.address.location.latitude

You can create a workspace where the location object will be the main object. Just use cd and enter the desired object:

cd user.address.location
latitude # => some value

If you want to go back, just use cd ... As you may notice, it works the same way as the navigation between directories in the command line. If you are unsure of what workspace you are currently in, type cwws and you will get information about the current context.

If you would like to see all the workspaces you created, type workspaces and you will receive an array of contexts. By using cd without dots you can immediately switch to the main context.

Inspect any class or object

If you would like to explore all methods, constants, and variables related to the given class or instance, you can use the ls command and pass the “thing” you want to explore:

user = User.last
ls user                     
# User#methods: name
# instance variables: @association_cache @attributes @destroyed
# @destroyed_by_association

The output is logically grouped so you perfectly know that is the source of each provided method that you can execute on the given object.

Output object in the YAML format

Not always objects are readable in their original form. For example, large hash with many pairs - it can be quite difficult to read the desired information from it. Thankfully, we can use a tiny helper method y to output the object in YAML format:

users_data = [ { first_name: 'John', last_name: 'Doe' }, { first_name: 'Tim', last_name: 'Doe' }]
y users_data

The output for the above code will be:

---
- :first_name: John
  :last_name: Doe
- :first_name: Tim
  :last_name: Doe

This method will be also useful with more complex objects like active record models.

Temporary alter any method of the object

If you don’t want to commit any changes to the codebase but execute code with changed elements during the console session, you can temporarily alter the method for the specific object. Given we have the following User class:

class User < ApplicationRecord
  def perform_action
    some_callback
  end

  def some_callback
    puts "original callback"
  end
end

If you want to change the some_callback method logic, you can modify it for one of the User instances:

user = User.last

def user.some_callback
  puts "modified callback"
end

user.perform_action
# => "modified callback"

another_user = User.first
another_user.perform_action
# => "original callback"

If the method you are updating is not public, you can ensure the proper visibility level after redefining it:

def user.some_callback
  "modified callback"
end

user.singleton_class.class_eval { private :some_callback }

The change will gone if you exit the console or assign the object again.

Make custom methods to be available in the console by default

If there are some methods that you are using all the time, or you use certain user record to perform some actions, you can provide the needed data in the form of helpers.

Given you use User.find(10) all the time to find the user that you later pass to the background job you start from the console level. You can create the following initializer:

Rails.application.console do
  puts "Loading custom initializer #{__FILE__}"

  def main_user
    User.find(10)
  end
end

After this change, you can start the console and use main_user to fetch the user that is proper for the case with background jobs execution.

If the custom console initializer is your own initializer for development purposes and other developers are not using it, you can add the file to .gitignore to make sure that you only use it locally.

High-Performance Active Record

Master the art of database optimization in Rails applications. Learn proven techniques to improve your Ruby on Rails application performance.

Interacting with the Rails environment

There are tasks that you can perform directly inside the console without the need to interact with the application in the browser, using the command line to execute Rake tasks or running unit tests to verify the way the given code works. In this section, I will focus on those tasks.

Manipulating helpers

By default, a helper object is available in the console. It exposes all of the methods defined in the app/helpers directory. Given you defined the following method in app/helpers/users_helper.rb

module UsersHelper
  def full_name(first_name, last_name)
    "#{first_name} #{last_name}"
  end
end

In the console, you can access the method without providing the module name:

helper.full_name("John", "Doe") # => "John Doe"

The same rule applies to the default helpers available in views like sanitize:

helper.sanitize("<h1>Hello world</h1><p>some text</p>", tags: %w[p]) # => "Hello world<p>some text</p>"

Inspecting routes

There are two ways you can inspect a given route that you previously defined in config/routes.rb file. Given that we defined show action for ArticlesController:

class ArticlesController < ApplicationController
  def show
    render json: { message: 'Single article' }
  end
end

With the following route definition:

resources :articles, only: %i[show]

You can inspect the route URL using the app object and passing the same path method you would use in the view or controller:

app.article_path(id: 6) # => /articles/6

Another way you can inspect the action is to perform the request to see the response code and body:

app.host = 'localhost'
app.get(app.article_path(id: 6))

app.response.status # => 200
app.response.body # => "{\"message\":\"Single article\"}"

Invoking rake tasks

A common way of invoking rake tasks is to use the command line. You can also do it from the console level. Given we have the following task defined in lib/tasks/users.rake:

namespace :users do
  desc 'Truncate user data for specified email'
  task :truncate, [:email] => :environment do |_t, args|
    puts "Truncating data for user: #{args[:email]}"
  end
end

From the console level we have to first load all tasks and then invoke the one we are looking for and pass arguments to the invoke method:

Rails.application.load_tasks
Rake::Task['users:truncate'].invoke('john@doe.com') # => "Truncating data for user: john@doe.com
"

When your task requires more arguments, pass them to the invoke method in the right order.

Reflecting changes in the code

When I talk about the Rails console and interacting with the environment, I can’t forget about the well-known method to reload the code inside the console to reflect changes without leaving the session:

helper.some_method
# => undefined method
reload!
# => Reloading ...
# => nil
helper.some_method
# => true
Improved thanks to Reddit user
In the case of reload! sometimes it does not work as expected, especially if you have some local context variables already. Sometimes it is cleaner to just use load "#{Rails.root}/app/lib/foo.rb" to reload a single file in the console.

Playing with methods

Rails console makes it possible to replace the command line in some cases but also the code editor. Have a look at how you can inspect your codebase without leaving the console.

Finding where the given method was defined

The class can have two types of methods: instance and singleton. If you know the name of the method and the name of the class that can be a caller, you can easily find in which file it’s defined and in which line the definition starts.

To inspect the instance method, use the following code:

User.instance_method(:name).source_location
# => ["/app/models/user.rb", 2]

As a result, you will receive two elements array where the first element is the path to the file and the second element is the line number where the definition starts.

For inspecting the class method, you can use singletion_method instead of the instance_method and the output will be in the same format:

User.singleton_method(:human?).source_location
# => ["/app/models/user.rb", 8]

Rendering the source of the method

This functionality is available only if you have the pry gem installed as the standard console does not provide it.

You don’t have to open a text editor to view the code of the given method. It’s useful, especially for external libraries. However, you have to keep in mind that you won’t be able to view the source of the method that was defined dynamically (lots of methods in Rails were defined that way).

In terms of the instance methods, grab the class name and invoke the instance_method on it by passing the method name and then calling the source on the result:

User.instance_method(:name).source
# => "  def name\n    \"\#{first_name} \#{last_name}\"\n  end\n"

The output is not well formatted, but you can simply improve it by calling the display method on the result:

User.instance_method(:name).source.display
# def name
#   "#{first_name} #{last_name}"
# end
# => nil

If you want to display the source of the class method, replace instance_method with singleton_method.

High-Performance Active Record

Master the art of database optimization in Rails applications. Learn proven techniques to improve your Ruby on Rails application performance.

Searching for methods

If you don’t know the exact name of the method, you can filter instance and class methods against regular expression and receive an array of method names matching passed criteria.

For instance, methods use the following code:

User.instance_methods.grep(/name$/)
# => [:name, :model_name, :store_full_class_name]

The expression we used above searches for all methods that end with the “name”. The grep method returns an array with matching names that you can later use to invoke the method or check its source.

For class methods, use singletion_methods instead:

User.singleton_methods.grep(/table_name$/)
# => [:schema_migrations_table_name, :internal_metadata_table_name, :table_name, :reset_table_name, :quoted_table_name]

Playing with Active Record

The ActiveRecord library itself makes the database interactions very quick and efficient but there are some tricks that you can use to make your work with console and database even more efficient.

Execute any SQL query

If you don’t want to interact with the database by using ActiveRecord models, you can quickly execute any SQL query against your database. To do this, call the execute method on the current database connection:

sql = "SELECT * FROM users"
results = ActiveRecord::Base.connection.select_all(sql)
results.to_a # => [...]

When using .select_all, the result will have the same format for all database engines. Beware of execute method as the result format might differ depending on the database engine you are using. For example, if you use PostgreSQL, the PG::Result instance will be returned.

Improved thanks to Reddit user
Do not recommend to use execute. Instead you should use select_all. exec_query is similar but select_all is the best choice. Both of these return a generic response for all DBs.

Reload query

If you executed the Active Record query and assigned it to a variable:

result = User.where(first_name: "John")

If you want to execute it again, you don’t have to write the code again. You can simply call the reload method on the Active Record result, and the query will be executed again:

result = User.where(first_name: John)
result.reload

You can do this when pulling a single record or pulling a collection. The reload method works as long as the result comes from Active Record.

Inspecting tables in the database

If you want to get the array with table names at your disposal, you can simply call the following line:

ActiveRecord::Base.connection.tables

On the other side, if you are interested in columns for a particular table, you can use another method that comes with the current connection object:

ActiveRecord::Base.connection.columns("users")

The above call returns an array of objects where each object represents one column and provides information about its type, name, and other attributes.

Join the newsletter. Pure knowledge straight to your inbox.

You can opt out anytime.