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.