6 Simple Tweaks to Improve your Productivity with Rails

In this three-part series, I present simple tweaks you can make to your Rails app that each take about 5 minutes. In the first part, we discussed five simple ways to tweak the performance of your Rails app. In this second part, we will talk about productivity, and ways you can shave time off of common tasks while developing a Rails application.

1. Make bundler use multiple cores to install gems faster

Bundler 1.4.0 introduced the ‘jobs’ feature which allows bundle installs to be run in parallel in multiple threads. Depending on how many cores your machine has, this can seriously reduce the time you spend staring at the console, waiting a bundle install to complete.

To take advantage of this feature of bundler, we can run the following commands:

number_of_cores=$(sysctl -n hw.ncpu)  
bundle config --global jobs $((number_of_cores - 1))  

The optimal jobs setting for bundler is 1 less than the number of cores your machine has. So first, we find out how many cores we’re working with, and then set the global config of bundler to be 1 less than that.

As demonstrated here: http://mervine.net/bundle-faster, this can shave minutes off of a bundle install on a large project.

2. Precompile your assets locally to save time on deploys

If you have even a moderate amount of css and js assets, chances are it takes seconds, and sometimes even minutes to compile, minify and uglify everything for production. However, if your assets are at a point where they’re not changing very much between deploys, you can shave that time off your deploys by precompiling your assets up front and storing them in version control.

-----> Preparing app for Rails asset pipeline
       Running: rake assets:precompile
       I, [2014-04-17T17:54:07.273555 #1263]  INFO -- : Writing /tmp/build_8945fb34-0238-41d7-a2fd-4402581a95fe/public/assets/application-10faafa06109fa14582542ac1852f5c5.js
       I, [2014-04-17T17:54:07.338617 #1263]  INFO -- : Writing /tmp/build_8945fb34-0238-41d7-a2fd-4402581a95fe/public/assets/application-9cc0575249625b8d8648563841072913.css
       Asset precompilation completed (11.26s)
       Cleaning assets
       Running: rake assets:clean

To do this, simply run the rake assets:precompile task, making sure to specify the production environment, so that the production version of the assets are generated.

$ RAILS_ENV=production bundle exec rake assets:precompile

This task creates a public/assets directory containing a manifest and your compiled production assets. You will now need to commit this directory to version control.

git add public/assets  
git commit -m "vendor compiled assets"  

Now that the computationally expensive process of precompiling your assets has been done up front, your deploy pipeline will use these ready-made assets rather than spending time recompiling them every time. However, if your assets change, you will need to remember to recompile them locally before deploying.

3. Step Up your Debugging Game

One thing Rails lacks is a good debugging solution. All too often, I end up littering my methods with p “here” or p “variable: #{variable}” just to see what’s going on in my code. Despite the lack of a full-featured and integrated debugging environment, there are some nice third-party gems you can use to make debugging a little simpler.

Pry

Pry is an alternative to the standard Rails console. Inspired by IPython, Smalltalk and other advanced REPLs, Pry supports features like source code and documentation browsing, syntax highlighting and the ability to view and replay history.

You can even add binding.pry in your code to drop your server into a live debugging session when it hits that line. This allows you to play with the current environment at runtime rather than printing variables.

To use Pry as your default Rails console, simply add the pry-rails gem to your Gemfile.

Better Errors

Better Errors turns the ugly stack track error message into an interactive, problem-solving workspace. Complete with a live shell and information about the request and the current states of local and instance variables at the time of the error, Better Errors gives you instant insight into what went wrong.

Better errors

To install Better Errors, simply add the following to your Gemfile:

group :development do  
  gem "better_errors"
  gem "binding_of_caller"
end  

The bindingofcaller gem is a dependency for the live shell. Also note it’s important that the gems be available only to the development environment. This way, your end users in the production environment don’t get access to the REPL and other sensitive information from the stack trace.

Awesome Print

Awesome Print is, truly, awesome. It takes boring, hard-to-decipher, un-awesome console output that looks like this:

And turns it into this:

Much better!

Include it in your Gemfile with gem awesome_print and use it with ap. It also has hooks to integrate with the Logger, IRB and Pry.

4. Use Bash/ZSH Aliases

It doesn’t matter if you use Vim, Sublime Text, Rubymine or something else entirely as your editor of choice, every Rails developer uses the command line throughout the day, and often for repetitive tasks. By mapping shortcuts to the functions you use most often, you can shave off a few seconds from these tasks. While a few seconds might not seem like much of a gain at first, if you perform the task many times a day, those seconds can really add up.

obligatory relavent xkcd:

Is it Worth the Time?

source: http://xkcd.com/1205/

Aliases have a very simple syntax. They can be added to your .bashrc or elsewhere in your load path.

Here’s a quick primer on the alias syntax and what you can accomplish with them.

Simple map

alias h=“heroku”  
alias g=“git”  
alias rk=“rake”  

Aliases are created starting with the alias keyword followed by newcommand=“oldcommand”. Using this syntax, we can map longer commands that we use all the time, like heroku to a single letter, h.

Map with arguments

alias rs=“rake db:migrate”  
alias rdm=“rake db:migrate”  

We can make our aliases more useful by taking commonly used combinations of commands and arguments, and mapping them to a single, easy to remember command.

Combining Multiple Commands

alias rdmt=“rake db:migrate && rake db:test:prepare”  

The && syntax allows us to chain multiple commands together in a single alias. If the first command succeeds, it will continue to execute the next command. If a command fails, the chain stops.

Accepting user input

alias commit=“git add -A && git commit -am $1”  

In this case, the $1 in the alias refers to the first additional argument that comes after the command. We would use this alias like: commit “fixed bug” which would act as if we typed: git add -A followed by git commit -am “fixed bug”.

Creating functions with bash script

function gc {  
  if [ -z "$1" ]; then
    git checkout master
  else
    git checkout $1
  fi
}

Bash script functions are like aliases on steroids. The function above says: if the user inputs the command gc by itself, then checkout the master branch with git checkout master. Otherwise, use the argument that comes after gc as the branch name. So gc hotfix would expand to git checkout hotfix

For additional alias insertion, check out some of the Oh My ZSH plugins (and consider switching to ZSH from Bash to make taking advantage of them simpler)

5. Use POW to tame multiple apps

Switching between multiple Rails apps can be a pain. You can configure RVM to handle multiple versions of Ruby, and use gemsets to keep different versions of gems from interfering. And then you can set each app’s server to use a different port to avoid conflicts.

Or you can use POW.

POW is a zero-config development server that handles all the typical headaches of developing multiple Rails apps at once.

POW can be installed with a single line:

curl get.pow.cx | sh  

and configured with two:

$ cd ~/.pow
$ ln -s /path/to/myapp

And with that, your app will now be running at http://myapp.dev/.

Pow works automatically with rbenv and Bundler to keep your ruby and gem versions straight.

6. Use Foreman to handle dependencies

If you have multiple dependencies that need to run alongside your app, like a Redis server, Sidekiq, or push notification server, Foreman can make managing these dependencies much simpler. Add gem foreman to the Gemfile and then create a file called Procfile.dev at the root of your application.

It might look something like this:

web: rails s  
redis: redis-server /usr/local/etc/redis.conf  
worker: bundle exec sidekiq -C config/sidekiq.yml  

Now, by running:

foreman s -f Procfile.dev  

all of your dependencies will be started together in the same terminal window. (You could even create an alias to make the command easier to remember!)

Conclusion

That’s it for productivity. Leave your favorite Rails productivity tip in the comments. Next week we’ll discuss sanity and simple things you can do today to make future-you a happy person.

If you found this article helpful, follow me on Twitter for more content like this.

Andrew Allen

Author of EfficientRails.com, Software Engineer @Munchery, Former startup founder.

comments powered by Disqus