When Do You Need a Require in a Rails Gemfile

When do you need a require in a rails Gemfile?

If you omit the :require option, by default Bundler will attempt to require the gem by using the standard name-to-file conversion rule:

dashes are considered namespace separators and underscore classname separators

It means that the following gem statements

gem 'net-sftp'
gem 'backup'
gem 'foo_bar'

are equivalent to

gem 'net-sftp', require: 'net/sftp'
gem 'backup', require: 'backup'
gem 'foo_bar', require: 'foo_bar'

This works well if the gem author has followed the standard conventions. But in some cases, for a variety of reasons, this doesn't happen.

For instance, there are gems called foo-bar where the main filename is /foo_bar.rb or even /foo.rb. In this case you provide the :require option to tell Bundler which file you want to require.

Finally, require: false is used when you want a gem to be part of the bundle, but you don't want Bundler to load it by default.

This is useful, for instance, to lazy-load a gem in case it is used only in certain circumstances. Think about a rake task that includes a heavy gem. You don't want your application to load it on boot, but it needs to be part of the bundle or it will not be found.

In this case you pass the option require: false. Then, in your rake task you will require it manually as usual

require 'library'

The library will be loaded only when the task is invoked, not in the normal application execution.

A good example is whenever. The library must be part of the bundler because it must be bundled when you deploy the app, but it is intended to be run as a command line script. For this reason, you don't want Bundler to require it when the Rails application is started.

There are cases where you use groups instead of require: false.

See also the official Bundler documentation for require.

What does `require:` mean in a Rails gemfile?

When the gem itself doesn't require any of its lib, you need to do that either in your Gemfile (the way you wrote) or in some file in your project.

Eg.: imagine a gem which has more than one solution for any particular problem. However, you don't want to load all of those solutions (files), you only need one. Then you'd need to specify which file you want to load by using require: some_lib.

When is the 'require' necessary when using a ruby gem?

Usually, an application that is using a gem needs to require the gem:

require "my_awesome_gem"
MyAwesomeGem.do_something_great

However, if an application is using bundler, which defines the application's gem in a file called "Gemfile":

source 'http://rubygems.org'
gem 'my_awesome_gem'

then the application may invoke bundler in a way that automatically requires all of the gems specified in the Gemfile:

require "bundler"
Bundler.require
MyAwesomeGem.do_something_great

Rails projects use Bundler.require, so a Rails application will not need to explicitly require a gem in order to use it: Just add the gem to the Gemfile and go.

For more about Bundler.require, see the bundler documentation

For more about how Rails uses Bundler, see How Does Rails Handle Gems? by Justin Weiss.

Do we need require and Gemfile at the same time?

The purpose of the Gemfile can be helpful so that you can insure your code will work by using bundler which allows you to run bundle install which will install the gems to work with the current version of ruby you will be using for your code. It will also add a Gemfile.lock file which is a good idea to commit in your version control to insure you have a working stack where the gems and the ruby version are all compatible.

If you only require the files in your script, there is no guaranteed that the gems are actually installed in the scope of that script's runner. So by having a Gemfile and Gemfile.lock and using bundler, you can have portability for your codebase.

Update

As per comment by @engineersmnky , you can specify gem version however with this syntax and it should work so long as those gems are installed. You would first need to make sure to install the version in your terminal:

gem install google_drive -v 2.1.11

Then you can do this in your ruby file

require 'rubygems' 
gem 'google_drive', '2.1.11';
require 'google_drive'
require 'typhoeus'
require 'json'
require 'pg'
require 'mandrill-api'

Bundler: What does :require = nil in Gemfile mean?

Yes, nil and false behave the same here: it makes Bundler not require the specified gem.

Attaching a gem to Rails to prevent require everywhere?

In the Gemfile, you can do these things:

# Require a different file than the gem's name
gem 'foo', require: 'bar'

# Install but not require anything.
# You need to manually require the gem somewhere.
gem 'foo', require: false

You can still add version and platform specification if you want.

Real-world examples are ActiveSupport and rspec:

gem 'activesupport', '~> 5.2', require: 'active_support/all'

gem 'rspec', '~> 3.1', group: :test, require: false

Gem needs to be required manually

It does not conform Rails autoloading rules. Create a file instagram_api_client.rb with a content

require 'instagram_api'

in the top level of lib folder. That should do the trick.

For gems, the name of the file to be loaded automatically should be exactly equal to the name of the gem.


Or, as suggested by @TomLord, one might simply specify

gem 'instagram_api_client', require: 'instagram_api'

in the Gemfile itself.

Ruby: What does 'require: false' in Gemfile mean?

This means install the gem, but do not call require when you start Bundler. So you will need to manually call

require "whenever"

if you want to use the library.

If you were to do

gem "whenever", require: "whereever"

then bundler would download the gem named whenever, but would call

require "whereever"

This is often used if the name of library to require is different than the name of the gem.

gem included in gemfile still requires include in class file?

There are a couple concepts that you'll want to understand about what is going on here:

In Rails, the Gemfile contains the libraries (gems) that you want bundler to download and make available to your app. These are automatically made available in Rails, where as in a standalone Ruby program, you would need the 'require' command for each library that you want to use. 'require' literally runs the file that is required (akin but not exactly the same as the '#include' directive in C++ and the 'import' in Java). The required file may add some kind of global functionality, or it may not. With the AASMgem, the functionality isn't desirable in all classes, so you decide which classes will use it with...

The Ruby command 'include' allows you to 'mix in' functionality from a module (module AASM in the following example, see: https://github.com/aasm/aasm/blob/master/lib/aasm/aasm.rb). Look at the following example from the AASM doc:

require 'aasm'

class Job
include AASM

aasm do
state :stage1, :initial => true
state :stage2
...
end
end

So, the 'require' statement is unnecessary in Rails, since Rails will have already requires the library for you. The 'include' statement mixes the state machine methods into the Job class. Specifically in this example, it gives you the 'aasm' method (that's a method, to which you're passing a block with the 'do'). The 'aasm' method does some stuff, and executes the block (which also uses the AASM-specific 'state' method in this example).

The main point here in relation to your original question is that the 'aasm' method does not exist in the Job class until you 'include AASM'. This also means, that other classes do not automatically have the AASM methods (which keeps the Object namespace clean).

The only way that you will get functionality in all classes by using the 'require' command is if the required file monkey patches Object (this is rarely done since it can be dangerous), otherwise, you'll generally be given a new kind of class to use or a collection of methods contained in a module that you can mix in to your own classes.



Related Topics



Leave a reply



Submit