Getting started with Ruby and Rails is quite different to many other programming environments. Instead of starting with an IDE and something visual to build on, you’re left at a command line with a plain text editor. If you’re not familiar with this style of development it can seem pretty confusing, some of the commands look arcane even.
For example, when running commands you often need to type “bundle exec” before a particular command. I use the “spinach” testing tool – to run my test suite I have to type “bundle exec spinach”. If I typed “spinach”, sometimes the test will load up and run OK, other times the tests will load but fail and some other times I just get an error.
Why does this happen? What are those two magic words?
To answer that we have to go back into the depths of time.
Or to about 2010.
In the old days, when you were handed a Rails project from someone else, you had no idea what its dependencies were. If you were lucky, someone had written them out (Rails had a mechanism for loading them via a rake task) – but there was no guarantee of this. So you would fire up the app and, by trial and error, figure out which gems needed to be installed to get it to run.
This changed with Rails 3, which used a tool called “bundler”. Bundler is separate to Rails and you can use it in any Ruby project you want, but its inclusion in Rails 3 made its name. And made Rails 3 a much more professional and dependable development tool compared to its predecessors.
Bundler uses a file called the Gemfile. This lists all the gems your application needs – along with the required version number.
At some point you run bundle install. This installs those gems, analyses their dependencies and then writes a file called Gemfile.lock – listing the dependencies and version numbers loaded. This means that when you deploy your app to the live server you can be sure that it’s using the same stuff that you’re running locally.
But that’s only half the story.
What’s to stop you loading up a gem on your development machine, referencing it in your application but not mentioning it in your Gemfile?
And if you did, then you’d find that we were back in the bad old days – you’d have a nice list of gems that may or may not be a description of what your app needs to run.
So that’s where bundle exec comes in.
By using “bundle exec mycommand”, you’re telling bundler to run mycommand but only load up the gems that are referenced in Gemfile.lock. If mycommand attempts to use anything outside of there it will fail to load and you will get an error.
Rails 4 onwards creates a “bin” folder with the rails and rake commands in there – these are designed to use bundler for you, so you can just type bin/rails or bin/rake. In fact bundler has a feature called “binstubs” that fills up your bin folder with “stubs” – little programs that load up the various gems in the correct environment, saving you the job of typing bundle exec each time.
So there you have it.
Bundle exec is a necessary piece of discipline you should follow to ensure that you keep track of the dependencies in your application.
Use it each time and you can be certain that your app will load up and behave in the way you expect. Avoid it and the results are … uncertain.