Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bundler Rails require different gem in development

I'm trying to set up a develoment environment for developing a Rails gem. I would like to load the gem from a local source in development mode and via rubygems in production. I would like to do something like the following:

Gemfile

group :production do
  gem 'my_gem', '1.0.0'
end

group :development do
  gem 'my_gem', :path => '~/apps/my_gem'
end

When I run the bundle command, bundler complains that you can't load the same gem twice. Is there a way to require different versions of a gem depending on the Rails environment?

like image 638
Patrick Klingemann Avatar asked Feb 28 '12 00:02

Patrick Klingemann


People also ask

How does bundler work in Rails?

Bundler provides a consistent environment for Ruby projects by tracking and installing the exact gems and versions that are needed. Bundler is an exit from dependency hell, and ensures that the gems you need are present in development, staging, and production. Starting work on a project is as simple as bundle install .

Is bundler a gem?

Bundler: a gem to bundle gems. Bundler makes sure Ruby applications run the same code on every machine. It does this by managing the gems that the application depends on.

How do I change my gem bundler?

To use different gem versions, you could use this pattern: your-gem _version_ . For example, bundle _1. 10.6_ -v . Hope that will help.

Where does bundler look for gems?

gem files your app uses in vendor/cache . Running bundle install will prefer gems in vendor/cache to gems in other locations.


2 Answers

I've had the same problem and solved like this:

if ENV["RAILS_ENV"] == "development"
  gem 'my_gem', :path => '~/apps/my_gem'
else
  gem 'my_gem', '1.0.0'
end

then you can run RAILS_ENV=development bundle on your local machine and run any environment related command through RAILS_ENV=development bundle exec

like image 67
mcasimir Avatar answered Sep 21 '22 10:09

mcasimir


Doing this defeats the purpose of using Bundler. The whole point is that the dependencies you're using are consistent no matter where your application is loaded, deliberately trying to circumvent that goal is just going to cause you problems.

What happens when your local version of that gem is different than the one released in Rubygems (perhaps because you forgot to release a new version?)? Your app may blow up and you won't be able to reproduce it in development, which is horrible.

As for why this isn't even conceivable to achieve with Bundler (at least now): what happens if the dependency versions for the Gem are different in the Rubygems version vs. the local version are different? Now your entire Gemfile.lock needs to have two completely different dependency graphs, and you're potentially introducing countless more points of failure in production that wouldn't exist in development.

That said, it's okay to temporarily change your Gemfile to the local version while making changes to the gem, but you should change it back and release a new version of the gem, then bundle update my_gem to update the Gemfile.lock accordingly.

like image 39
Andrew Marshall Avatar answered Sep 18 '22 10:09

Andrew Marshall