how to require different gems with the same name? - ruby-on-rails

I am interested in making an application that requires me to require a gmail gem for ruby.
Right now there are 2 gems:
https://github.com/dcparker/ruby-gmail
https://github.com/nu7hatch/gmail
Both gems have the same require name, ie: gmail
The second one is much clear but there is a problem with one of its method. This method works well in the first gem (link). So I was thinking maybe I could require the first one for just that method. Is it possible to do so, how?

As others answers and comments have said, you cannot simply require both gems as they are.
However, given that both are hosted on GitHub, you could fork one of them and rename the offending classes. So long as your renaming is consistent within the gem you could use your fork within your Gemfile
Of course, you wouldn't be easily able to rebase changes onto your fork easily but if you really must use both gems this might be a compromise that you are happy with.

You could add the following to your Gemfile:
gem 'gmail', :git => "git://github.com/dcparker/ruby-gmail", :branch => "master"
gem 'gmail', :git => "git://github.com/nu7hatch/gmail", :branch => "master"

Related

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

I'm doing a tutorial on authentication and came across the following line for gemfile. What is the use of require here?
gem 'google-api-client', require: 'google/api_client'
Tutorial: http://willschenk.com/setting-up-devise-with-twitter-and-facebook-and-other-omniauth-schemes-without-email-addresses/
I understand require in Javascript, but in Rails I thought the gemfile is for installing gems, and once they are installed they can be used in the application, and thats all there is to it... so I'm not sure why I would use require.
I'm particularely interested because after adding this line and starting the server, I ran into an error.
Error:
/usr/local/rvm/gems/ruby-2.3.0/gems/bundler-1.11.2/lib/bundler/runtime.rb:77:in
`require': cannot load such file -- google/api_client (LoadError)
Temporary solution: I've commented out the require: part and the error is prevented. But maybe this is not ideal.
So understanding the use of require would help very much in troubleshooting this.
I read other articles on SO, but they discuss specifics like require => nil and require => false, which I think is a little different from my question.
Bunder: What does :require => nil in Gemfile mean?
Bundler: What does :require => false in a Gemfile mean?
Can anyone share some incite?
UPDATE
I later found this which explains it well: 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:
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.
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.

Ruby on Rails asking to put require and enable?

I'm not sure where to put require and enable?
I'm trying to use the instagram api, but it's telling me to put
require "sinatra"
require "instagram"
enable :sessions
in the sample application : https://github.com/Instagram/instagram-ruby-gem
But I'm new to learning rails, so I'm just trying figure some bits out,
Thanks
Thats for a sintatra app, not a rails app, for rails all I think you need to do is add it to your gemfile like so.
gem 'instagram'
If you still can't use it try adding :require, though I don't think you should have to.
gem 'instagram', :require => 'instagram'

Github: cloning an older version of an Rails gem

There's a Rails forum gem I like called Forem https://github.com/radar/forem However, the gem author made some changes to it that negatively impact my intended use. He added a moderation tool, whereby all new/unapproved users need their first post approved before it's displayed to the forum. This essentially mean that a moderator needs to be present all the time or the forum will have a hard time get going. This is a recent addition to the app.
Since github is version control, I'm wondering if there's a way to clone or use (I just want to use it, not modify it) an older version of the gem so I can use a version before the moderation was added.
Thanks if you can help.
You have some options (all goes into Gemfile):
gem 'forem', github: 'radar/forem', ref: 'ref that you want'
or
gem 'forem', github: 'radar/forem', tag: 'tag that you want'
or
gem 'forem', github: 'radar/forem', branch: 'branch that you want'
All of it is described in Gemfile docs

How do Ruby Gems Load in Rails?

Say I have a ruby gem that I want to use, but it's use is only needed in one model or controller.
Is there a way to load that gem exclusively for that one model or controller?
Would it be a waste of resources for it to be available systemwide (callable from any controller)
The answer posted is incorrect, it's perfectly possible to only load a gem for a particular model or controller. Your Gemfile allows you to define groups that Bundler can use to require certain gems. By default, any ungrouped gems along with the gems for the environment you are currently running in are required, and any named groups are not required. So if you had the following Gemfile:
gem 'always_used_gem', '1.0.0'
group :rarely_used do
gem 'rarely_used_gem', '1.0.0'
end
Then rarely_used_gem would not be required on initial application load. If you had a particular method that needed that functionality, you could do this:
def do_stuff
Bundler.require :rarely_used
# use stuff from rarely_used_gem
end
One note: make sure the Bundler.require is inside a method call or something like that, or else the group will be required when the file is parsed (i.e. application boot)
In terms of whether you want to do this, it should really only be used for exceptional circumstances. You're trading boot speed for execution speed by doing this, which might make sense in development but probably doesn't in production. Also, you can use this method if you have some incompatibilities between two gems (we use this to resolve issues between a couple of AWS gems, for instance.)
No, it's not possible. Once a gem has been loaded it will be available for all controllers / models / everything. This should not be a primary concern for you. RAM and CPU time is cheap, programmer's time is not.
Bundler autoloads/-requires all gems, unless
#Gemfile
gem :somegem, :require => false
Then you can do require it when you need it
#some_ruby_file.rb
#within_some_context
require 'somegem'
How useful it is and when to do this (except for when the load order is important, as for the mocha gem (needed to be loaded last)), I don't know. I leave this to your own judgement.

Why do names of Rails gems & plugins sometimes contain author name?

When it comes to adding gems/plugins I notice that sometimes the author name is prepended to the gem/plugin name, whereas other times it isn't. Is there any reasoning behind this?
Example:
config.gem "thoughtbot-factory_girl", :source => "http://gems.github.com"
Why not have it as:
config.gem "factory_girl", :source => "http://gems.github.com"
When do you differentiate between the two?
When GitHub used to auto-build and host gems, they enforced a namespacing scheme by username. This is why github gems are prefixed with a username. GitHub embraces forking projects; hence the need for the prefixed usernames. GitHub was never really a good place for the canonical gem names, so they decided to drop their automatic gem hosting* when Gemcutter launched. Since then, even the original host of canonical gems, RubyForge, stopped hosting gems in favor of Gemcutter. Gemcutter is now the canonical source for all gems.
To make this easy for everyone, http://gems.rubyforge.org now points to http://gemcutter.org.
*GitHub announced that they would continue to host all old username namespaced gems for at least one more year.
With regards to factory_girl, that too is now hosted on Gemcutter. Your config only needs to look like this now:
config.gem "factory_girl"
...but I suggest also adding a version number for your projects (you'll thank me when you come back to a stale project later):
config.gem "factory_girl", :version => "1.2.3"
Because there are several projects with similar funcitonality, but provided by different authors. Maybe some of them are forks of the other ones. Or maybe they just have a common interface for a specific task.
Quick googleing yields the following authors:
javan's factory_girl
thoughtbot's factory_girl
mattmatt's factory_girl
To distinguish them, it's useful to prepend author's nickname to gem name.

Resources