The Pragmatic Studio

Rails Console Shortcuts, Tips, and Tricks

March 11, 2019

As a Rails developer, you’ll end up spending a lot of time in the Rails console. It’s like a back door to your application. Using the console lets you interact with parts of your app directly from a command-line interface without going through a browser. And once you’re comfortable using the console during development, it feels quite pedestrian to have to go through the front-door browser.

To help you get the most out of your time in the console, here’s a collection of shortcuts, tips, and tricks.

Clearing the Console

To get a clean slate in your console, use Command + K on the Mac. You can also use Ctrl + L to clear the screen, which works on both Mac and Linux. If you’re on Windows, the only way we’re aware of to clear the console is by typing system('cls'). The Windows cls command clears the screen, and the Ruby system method runs that command in a subshell.

Reloading the Console

The Rails development environment is streamlined for rapid feedback. You can make code changes in your favorite code editor, then hit Reload in your browser to quickly see the effect of those changes. This works because your application code is automatically reloaded on every request when you’re running in the development environment.

The console also runs in the development environment by default, but it does not automatically reload code. Once a file has been loaded, it’s cached for the duration of the console session. You can refresh the code by exiting the console and starting a new session, but that’s tedious to do every time you change code.

Instead, use the reload! command to pick up the latest version of your code:

>> reload!
Reloading...
=> true

Any objects that existed prior to the call to reload! still reflect their previous version. For example, if you have a movie object initialized in the console and then in your editor you define a new method in the Movie class, the movie object won’t have that new method even when you call reload!. After calling reload! you’ll need to reinstantiate objects that have changed.

Searching Command History

Once you’ve run a line of code in a console session, you often want to re-run the same code later or edit it to do something slightly different. You’ve got a couple options for recalling commands.

The console maintains a history of commands which you can navigate using the up and down arrow keys. To recall the previous line you entered, hit the up arrow key. Keep hitting it to scroll further back in time. Once you’ve gone back, you can go forward using the down arrow key.

As your session history builds up, finding what you’re looking for using the arrow keys can be more work than just re-typing the code. There’s gotta be a better way, and indeed there is! If you’re on a Unix machine and using the default bash shell, then you can search for a prior command by pressing Ctrl + R and then typing any part of that command. It will search backwards in the history and autocomplete the first command that matches what you typed. The more you type, the more it narrows down the search. Once you’ve found the command you’re looking for, press Enter to run it. Or press any arrow key to start editing the command. Or continue to press Ctrl + R to successively walk back through matching commands.

Searching with Ctrl + R also works on the standard command line. So once you get comfortable with this shortcut, you save time in both environments.

Autocompleting

Yup, the console has autocompletion support, too.

Suppose you have a Movie model that you previously used in the console and now you want to use it to run a query. Start by typing Mov and then hit Tab:

>> Mov<Tab>

There’s only one possible completion in this case, so it’s autocompleted to what you want:

>> Movie

Given the class, you now want to use the where method to run the query. Start by typing .w and then hit Tab:

>> Movie.w<Tab>

There’s more than one valid completion in this case, so nothing happens (you may hear a bell). Now hit Tab a second time and you’ll get a list of valid completions:

>> Movie.w<Tab><Tab>

Movie.where                 Movie.with_scope
Movie.with_exclusive_scope  Movie.with_warnings
Movie.with_options

You want the where method, so type the next character in the method name (h) and hit Tab yet again:

>> Movie.wh<Tab>

Bingo. That narrows it down to only one possible completion, so it’s expanded to what you want:

>> Movie.where

Autocompletion saves a lot of typing and remembering. When in doubt, just keep hitting the Tab key. It will autocomplete class names, method names, and any variable/object names within the scope of the console session.

Getting the Value of the Last Expression

This one comes in handy all the time! Here’s an all-too-familiar situation: You manage to correctly type a useful hunk of code into the console, such as this query:

>> Movie.where("total_gross >= ?", 100000000).order(:title)

Then you immediately hit Enter and the query runs. Then you remember that you actually wanted to do something with the results, but failed to assign the results to a variable. At this point you could hit the up arrow key to recall that line of code and then edit it, but there’s an easier way.

The return value of the last expression is automatically stored in the special underscore (_) variable. To assign the query results to a movies variable, for example, you can use:

>> movies = _

Then you can actually do something with the results, such as counting the number of movies:

>> movies.size
=> 5

Alternatively, you could have called the size method directly on the _ variable:

>> _.size
=> 5

It’s important to keep in mind that _ always contains the value of the last expression. So at this point the value of _ has changed to be the result of calling size on the array of movies:

>> _
=> 5

Neat little trick, that one.

Trying Out View Helpers

Want to try out a view helper before embedding it in a view template? Using the appropriately-named helper variable, you can run any view helper directly in the console. This comes in handy for experimenting with the built-in view helpers:

>> helper.pluralize(3, 'mouse')
=> "3 mice"

>> helper.number_to_currency(1.50)
=> "$1.50"

>> helper.truncate("Iron Man", length: 7)
=> "Iron..."

But wait, there’s more! You can also use it to play around with custom helper methods that are specific to your app:

>> helper.title_tag(Movie.first)
=> "<title>Flix - Iron Man</title>"

>> helper.poster_image_for(Movie.first)
=> "<img alt=\"Ironman\" src=\"/assets/ironman.png\" />"

Trying helpers directly like this sure beats the typical edit-reload cycle.

Trying Out Route Helpers

Along the same lines, it’s often convenient to experiment with route helper methods in the console. To do that, call the methods on the implicit app object:

>> app.movies_path
=> "/movies"

>> app.movie_path(Movie.first)
=> "/movies/1"

Use the helper and the app objects together, and you can generate links in the console:

>> helper.link_to("Movies", app.movies_path)
=> "<a href=\"/movies\">Movies</a>"

>> movie = Movie.first
>> helper.link_to(movie.title, app.movie_path(movie))
=> "<a href=\"/movies/1\">Iron Man</a>"

Just remember: If you make any changes to the routes.rb file, you’ll need to call reload! in the console to load the new route definitions.

Issuing Requests Interactively

The app object can also issue faux requests into your app, mimicing what a real user might do. We tend not to do this very often, but it can be quite useful for one-off interactions with the app from the console. The best part is that no browser or server is required.

Here’s a quick test drive to give you a feel for what’s possible:

>> app.get "/movies"
=> 200

>> app.get "/users/1"
=> 302

>> app.response.redirect_url
=> "http://www.example.com/session/new"

>> app.post "/session", email: 'fred@example.com', password: 'secret'
=> 302

>> app.response.redirect_url
=> "http://www.example.com/users/1"

>> app.session[:user_id]
=> 7

For more details on the methods you can call on the app object to issue requests, check out the ActionDispatch::Integration::RequestHelpers documentation.

Setting a Default Object

Here’s a neat trick that you won’t use very often, but it’s always fun to show off a little. Suppose you’re working with a movie object and calling methods on it:

>> movie = Movie.first

>> movie.title
=> "Iron Man"
>> movie.rating
=> "PG-13"
>> movie.director
=> "Jon Favreau"

If you plan to spend a few minutes just messin’ around with that object, it would be nice to avoid typing movie. every time you want to message that object. To do that, you can set movie as the default object like so:

>> irb movie

The irb command is a reminder that the console is a souped-up interactive Ruby (irb) session, so this actually creates an irb subsession.

Now whenever you call a method, it’s in the context of the default movie object:

>> title
=> "Iron Man"
>> rating
=> "PG-13"
>> director
=> "Jon Favreau"

To exit the subsession and return back to the original context, type exit:

>> exit
=> #<IRB::Irb:  . . .>

Another example of when this might come in handy is sending requests using the app object. Set app as the default object and from then on you can easily issue multiple requests:

>> irb app

>> get "/movies"
=> 200

>> get "/users/1"
=> 302

Playing in the Sandbox

The console is generally a fun environment to play around in, but it can feel a bit too “live” if you have to worry about goofing up the database. Sometimes you’d like to experiment with data in the console without the fear of permanently changing data. That’s when you’re glad you know about the --sandbox option:

$ rails console --sandbox
Loading development environment in sandbox
Any modifications you make will be rolled back on exit
>>

As indicated, any database changes you make will be rolled back when you exit the session.

Let’s try to delete a user:

>> User.destroy(1)

>> User.find(1)
ActiveRecord::RecordNotFound: Could not find User with id=1

>> exit
   (12.3ms)  ROLLBACK

The user was successfully deleted, but notice that the database transaction got rolled back after the exit. It’s like pushing the Undo button. By running everything within a database transaction and rolling it back at the end, any database modifications made during the session are returned to their original state.

Let’s double-check by starting a new console session and trying to find the user we just deleted:

$ rails console
>> User.find(1)
>> #<User id: 1, ...>

No worries!

Switching Environments

By default, the console fires up in the development environment as indicated by the helpful message:

$ rails console
Loading development environment
>>

That’s usually what you want, but you can also start a console in a particular environment by tacking on the -e option and specifying an environment name. For example, if you want to use the console to poke around with test data the test environment, use

$ rails console -e test
Loading test environment
>>

Or when you need a backdoor to your production environment, use:

$ rails console -e production
Loading production environment
>>

To play it safe, you may want to get in the habit of always running in sandbox mode when using a console in the production environment:

$ rails console -e production --sandbox
Loading production environment in sandbox
Any modifications you make will be rolled back on exit
>>

Then, when you really need to change production data, you can switch back to the live console.

Going to the Source

While playing around in the console you may want to see where a particular method is defined or how it’s implemented. For example, suppose you have a Movie class that defines an average_stars instance method, which you just used in the console like so:

>> movie = Movie.first
>> movie.average_stars

Now you’re wondering where that average_stars method is defined. Thankfully, Ruby can tell you exactly where to find that method. Here’s how:

>> location = Movie.instance_method(:average_stars).source_location
=> ["/Users/mike/flix/app/models/movie.rb", 39]

This is a two-parter: The first step is to get ahold of the average_stars method itself. We do that by calling the instance_method method on the Movie object, passing in the name of the method we want. This returns a Method object that represents the average_stars method. Given a Method object, we can ask it for its source location. The source_location method returns an array with two elements: the name of the source file that defines the method and the line number where it’s defined.

Now that we know the file and line number, we’d like to automatically open that file in our favorite editor positioned at the line so we could see how the method is implemented. Turns out, you can do exactly that from inside the console!

With VS Code, for example, you can run the code command with the --goto option to pass in file name and line number, separated with a colon. So from inside of the console, you can launch VS Code and go directly to the average_stars method using:

>> `code --goto #{location[0]}:#{location[1]}`

Using backquotes executes the enclosed string as an operating-system command.

Similarly, if you’re using SublimeText, you just run the subl command and separate the file name and the line number with a colon:

>> `subl #{location[0]}:#{location[1]}`

If you’re a TextMate fan, the mate command takes an -l option to indicate the line number:

>> `mate #{location[0]} -l #{location[1]}`

This same technique works for finding code in gems, as well. For example, suppose you were curious how ActiveRecord implements the update method. Going directly to the source is the best way to find out:

>> location = Movie.instance_method(:update).source_location

>> `code --goto #{location[0]}:#{location[1]}`

To take it a step further, check out this extended example.

Honestly, we don’t know what we’d do without this interactive environment. We generally have a console window (or three) open all day long, and if you peek over the shoulder of any Rails developer you’ll likely see the same. Practice these shortcuts and see if they don’t make you a happier, more productive, Rails developer.

Ruby and Rails Pro Bundle

Ready to become more confident with Ruby and Rails? There's no better set of courses to put you on a path to success than our popular Ruby and Rails Pro Bundle.

Rails Course