Invoke Rails and Rake Faster!
A handy shell function for running rails and rake commands with fewer mistakes.
As a Ruby on Rails beginner I would always confuse the rails
and rake
commands. Database migration? rake
. Database console? rails
. It seemed arbitrary. Later I learned the differences, but still I found myself making fat-finger mistakes between the two. And on top of that, rails
and rake
can be slow, meaning every mistake can come with a few-second penalty. Finally I got fed up and scripted the following solution in bash.
.bashrc
# Shortcut for `bundle exec rails` and `bundle exec rake`.
# If bin/rails and bin/rake are available, use them instead as they are much
# faster to execute than `bundle exec`.
function r() {
if [[ "g|generate|c|console|s|server|db|dbconsole|r|runner|new" =~ $1 ]]; then
if [ -x bin/rails ]; then
bin/rails "$@"
elif [ -x script/rails ]; then
script/rails "$@"
else
rails "$@"
fi
else
if [ -x bin/rake ]; then
bin/rake "$@"
elif [ -x script/rake ]; then
script/rake "$@"
else
rake "$@"
fi
fi
}
What I’ve done in my .bashrc (see my dotfiles) is defined a shell command r
that invokes rails
or rake
depending on the arguments given. If your argument to r
is generate
, console
, server
, dbconsole
, runner
, new
, or the one-letter aliases for those, the r
command assumes you meant to invoke rails
, and does so. Otherwise it assumes you meant rake
.
For example:
r db:migrate
== migrating....
r db
Welcome to psql 8.3.17, the PostgreSQL interactive terminal.
r s
=> Booting WEBrick
Short and sweet. No more fat-finger mistakes.
script/rails or bundle exec rails?
You’ll notice that r
also favors script/rails
over bundle exec rails
. You may wonder why; after all we’ve been taught to always use bundle exec to ensure correct behavior of executables in a Rails project. But this is actually overkill for the rails
command.
As it turns out, bundle exec rails
simply invokes script/rails
, which in turn initializes Bundler anyway. So bundle exec rails
therefore runs Bundler’s setup twice, and for no good reason. (Actually, Bundler.setup is invoked three times!)
In fact, in my testing script/rails
is up to 1 second faster than bundle exec rails
. The upshot is that the r
command should prefer to use script/rails
if possible.
June 10, 2013 update: Rails 4 muddies the waters even further: the rails
executable is now in bin/rails
. The good news is that r
will do the right thing, first trying bin/rails
(Rails 4 convention) and then script/rails
(Rails 3 convention).
script/rake
A script/rake
file is not included in standard Rails 3 projects, but you can use the same trick to get a 1-second boost over bundle exec rake
. This may qualify as a hack, so proceed with caution.
#!/usr/bin/env ruby
# script/rake
# Run rake after loading Rails/Bundler; faster than `bundle exec rake`
APP_PATH = File.expand_path('../../config/application', __FILE__)
require File.expand_path('../../config/boot', __FILE__)
require 'rake'
Rake.application.run
And don’t forget:
chmod a+x script/rake
June 10, 2013 update: Rails 4 includes a very similar rake script. It is in bin/rake
for new Rails 4 projects.
Wrapping up
Pretty straightforward, right? I find that this simple r
command is now an indispensable part of my Rails toolkit. Compared to straight up rails
and rake
, it’s fewer keystrokes, fewer mistakes, and a bit faster to boot.
You just read
Invoke Rails and Rake Faster!
A handy shell function for running rails and rake commands with fewer mistakes.
Share this post? Copy link
About the author
Hi! I’m a Ruby and CSS enthusiast, regular open source contributor, software engineer, and occasional blogger writing from the San Francisco Bay Area. Thanks for stopping by! —Matt