What does bundle exec rake db:migrate
mean? Or just bundle exec rake <command>
in general?
I understand that bundle
takes care of maintaining things in the Gemfile. I know what the word "exec" means. I understand that rake
maintains all the different scripty things you can do, and I know that db:migrate
is one of those. I just don't know what all these words are doing together. Why should bundle
be used to execute rake
to execute a database migrate?
You're running
bundle exec
on a program. The program's creators wrote it when certain versions of gems were available. The program Gemfile specifies the versions of the gems the creators decided to use. That is, the script was made to run correctly against these gem versions.Your system-wide Gemfile may differ from this Gemfile. You may have newer or older gems with which this script doesn't play nice. This difference in versions can give you weird errors.
Bundle exec
helps you avoid these errors. It executes the script using the gems specified in the script's Gemfile rather than the systemwide Gemfile. It executes the certain gem versions with the magic of shell aliases.See more on the man page.
Here's an example Gemfile:
Here,
bundle exec
would execute the script using rails version 2.8.3 and not some other version you may have installed system-wide.When you directly run the rake task or execute any binary file of a gem, there is no guarantee that the command will behave as expected. Because it might happen that you already have the same gem installed on your system which have a version say 1.0 but in your project you have higher version say 2.0. In this case you can not predict which one will be used.
To enforce the desired gem version you take the help of
bundle exec
command which would execute the binary in context of current bundle. That means when you use bundle exec, bundler checks the gem version configured for the current project and use that to perform the task.I have also written a post about it which also shows how we can avoid using it using bin stubs.
It means use rake that bundler is aware of and is part of your Gemfile over any rake that bundler is not aware of and run the db:migrate task.
bundle exec
is a Bundler command to execute a script in the context of the current bundle (the one from your directory's Gemfile).rake db:migrate
is the script where db is the namespace and migrate is the task name defined.So
bundle exec rake db:migrate
executes the rake script with the commanddb:migrate
in the context of the current bundle.As to the "why?" I'll quote from the bundler page:
It should probably be mentioned, that there are ways to omit
bundle exec
(they are all stated in chapter 3.6.1 of Michael Hartls Ruby on Rails Tutorial book).The simplest is to just use a sufficiently up-to-date version of RVM (>= 1.11.x).
If you're restricted to an earlier version of RVM, you can always use this method also mentioned by calasyr:
The
bundler_stubs
directory should then also be added to the.gitignore
file.A third option is to use the
rubygems-bundler
gem if you're not using RVM:I have not used bundle exec much, but am setting it up now.
I have had instances where the wrong rake was used and much time wasted tracking down the problem. This helps you avoid that.
Here's how to set up rvm so you can use bundle exec by default within a specific project directory:
http://robots.thoughtbot.com/post/15346721484/use-bundlers-binstubs