linkyndy
linkyndy

Reputation: 17900

Why does Bundler.require not require dependencies?

I am developing a gem at the moment. Here's how the .gemspec looks like:

gem.add_dependency 'activerecord', '~> 4.2'
...

gem.add_development_dependency 'rails', '4.2.5'
...

and here's my Gemfile:

source 'https://rubygems.org'

gemspec

I am setting up my main file, lib/my_gem.rb like so:

module MyGem
  module Lib
  end
end

ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)

require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
Bundler.require

However, if I start bundle console from my gem's folder, the dependencies are not required:

$ bundle console
Resolving dependencies...
irb(main):001:0> Rails
NameError: uninitialized constant Rails
...
irb(main):002:0> ActiveRecord
NameError: uninitialized constant ActiveRecord
...

What am I doing wrong?

Upvotes: 1

Views: 697

Answers (1)

jrochkind
jrochkind

Reputation: 23317

I believe dependencies included via the gemspec command in the Gemfile are not automatically required by Bundler.require. Only gems listed directly in the Gemfile itself are.

Additionally, gems included in only certain Bundler groups, like 'development', may not be required by a Bundle.require even if they were included directly in the Gemfile, you need to tell bundler to require groups other than default.

You can always require gems manually though, like require 'rails'. Bundle.require doesn't do anything but require gem for each gem in your Gemfile (or at least default group in your Gemfile), it's doing any magic other than looking up all the gems in your Gemfile and requiring them. Bundle.require is considered by some to be a bad practice anyway, you should just require the dependencies you need in the files you need them, some say. Although Rails doesn't agree, and Rails apps have their own somewhat complicated way of auto-loading things.

But if you are in a Rails app, as your example dependencies suggest... why are you doing any require 'bundler/setup' or Bundle.require yourself at all though, instead of letting Rails boot process take care of it? Rails boot process will take care of requiring the Bundler groups you probably expect too (like the "development" group when in Rails.env == 'development').

You can use the bundler api yourself directly like you're doing, it's not too hard. But Rails ordinarily takes care of this for you, and if you are using Rails, rails probably already has done a Bundler.setup and Bundler.require as part of Rails boot process.

Upvotes: 1

Related Questions