Almost everyone I know who writes any Ruby outside of the irb REPL uses Bundler. And everyone I know uses RVM to manage their rubies and their gems locally, except for this one guy who uses rbenv (which is a great tool, more on that in another blog post).
I have observed people use different strategies and workflows with bundler and RVM, since there is at least one overlap in what they do: manage collections of rubygems. Bundler calles them bundles and RVM calles them gemsets.
Broadly, here are two patterns.
Pattern #1
When a new project is cloned or intialized, an RVM gemset is created with the project’s name. Then, every time one wishes to work on that project, they switch to that gemset using the .rvmrc.
Pattern #2
When cloning or initilizing a new project on the system, no gemsets are explicitly created in RVM. Instead, bundler is used to manage all gemmy things across the system and across projects.
bundle install --path .gems
This --path
helps keeping the global RVM gem-space always empty (except for bundler.gem, rake.gem and rails.gem, to initlialize new projects.)
This also results in one’s .bundle/config
file to now contain the entry
BUNDLE\_PATH: .gems
And of course, .gems should be ignored by your SCM.
echo ".gems" \>\> .gitignore \# if you use git.
protip: I also include .gems when I create my tagfile. This helps me to quickly jump into the gem’s codebase using my editor.
Why do I shamelessly try selling Pattern #2 to everyone I meet?
Bundler is closer to the project while RVM is closer to the system. I like to have my project’s gems in my project’s directory managed with a tool built for the job.
Bundler stays with you in production.env while RVM might not, depending on the sysadmin and the situation at hand. I uniformly work on a philosophy of keeping my development as close to production with regards to the toolchain. No, I don’t run RHEL on my laptop.
One additional step encountered is prefixing every command that needs to run in the project context by bundle exec
(I have it aliased to bx
).
Which is only fair, since that is how every command would run on production.env.
e. g. bundle exec rake db:migrate
or bx rails dbconsole
protip: Forgot to prefix bx
to the previous command? Run bx !!
.
UPDATE: @tdinkar pointed me to passing the --binstubs
flag to bundle install that gets rid of having to use bundle exec
for every executable command to be run in the bundled context.
Here is Yehuda’s blog post delving into more detail about the --binstubs
flag and the reason for its existence.