The Ruby (and Rails) community is all about community based code sharing. There are many libraries out there that allow you to quickly and easily implement otherwise complex pieces of code that would take months to write on your own. The easiest way for any Rails application to exploit this is via the Gemfile. The Gemfile, along with the bundler command, allows you to quickly and easily specify which versions of which gems you wish to use in your application. Take the simplest example:
In this example, the omniauth-google-oauth2 gem provides a means to authenticate using Google's own sign in process. Actually implementing this functionality becomes a 15 minute job rather than a 2 week job. Adding this gem file and then running a
bundle install would install this gem, making it available for your application.
The problem with using the earlier example is that it will always grab whatever version is out there floating around. if you happen to send your source code to a friend or coworker and he runs a bundle install, he may get a completely different version of the gem than you did, one which may potentially contain changes that break your app. Luckily you can lock your gem down to a specific version or a specific major revision. To lock your gem down to a specific version, you specify the version as the second parameter. For example:
gem 'rails', '4.0.1'
This says that you want to use version 4.0.1 of the Rails framework. If a friend runs a bundle install on his machine, he'll also grab version 4.0.1 of the Rails framework.
You can also tell bundler that you wish to use any minor revision in the series using the
~> specifier. For example:
gem 'rails', '~>4.0.1'
If you run a
bundle update or a
bundle install on a new machine and Rails 4.0.2 is out, Rails 4.0.2 will automatically be installed and used for the application. However, even if Rails 4.1 is out, Rails 4.0.x will continue to be used, because only minor releases are allowed.
The final version specifier worth mentioning is the
>= specifier. This tells bundler to always require the version of the gem be greater then that specific version. For example:
gem 'rails', '>= 3.2'
This line tells bundler to use a Rails Version that is equal to or greater than 3.2. This can mean anything from 3.2.15 to 4.1. Be careful with using this in your application, as using it in the wrong way can once again, cause problems. However, you can specify a range of versions of gems that your application is compatible with. For example, if we know that our application works fine with cucumber 1.3.2 through 1.3.9, we can use this:
gem 'cucumber', '>=1.3.2', '<1.3.10'
By default, bundler gets the gems from rubygems.org. This is specified via the
source line at the top of the Gemfile. You can alternatively get gems from other places. Simple change the
source line to something else. For example:
Changing the source line from RubyGems to the GitHub gems server will pull gems from GitHub by default. You can also specify a second source for RubyGems by specifying multiple source lines. For example:
source 'https://rubygems.org' source 'http://gems.github.com'
This will tell bundler to use both RubyGems as well as GitHub as a source of gems. You could even, in theory, start your own gem server, and have your app always use that server.
Alternatively, you may wish to grab the source for a gem directly from git. A good example of this is when an employee is working on a gem is a work in progress. You can do this using the git specifier. For example:
gem 'nokogiri', git: 'git://github.com/tenderlove/nokogiri.git', branch: '1.4'
This example would grab the latest nokogiri source code right from the 1.4 branch of the git repository. Alternatively, you can specify github directly. For example:
gem 'rails', github: 'rails/rails'
Specifying this would grab the latest bleeding edge version of Rails from GitHub.
That's it! Thanks for reading!