Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use two gems in same namespace in Rails

I have an app that uses the LinkedIn gem but I need to move towards using the LinkedIn OAuth2 implementation which comes in a different gem.

I need to support the requests on oAuth1 in the initial gem for existing users, but I need to support OAuth2 for new users going forwards.

The problem is, both of these gems use the LinkedIn namespace for their module names, and depending on what order I include them in my Gemfile, one clobbers the other.

I tried adding require: false to the gemfile like so:

gem 'linkedin', require: false
gem 'linkedin-oauth2', require: false

But weirdly enough when I go to my console, the first one is still being required, where as the second one is not:

irb(main):001:0> require 'linkedin'
=> false
irb(main):002:0> require 'linkedin-oauth2'
=> true

Is this something to do with how require works? Is it possible to load just one of these gems each in separate lib files without clobbering each other?

EDIT

I figured out that I was requiring the linkedin in one of my spec files, which was causing it to be autoloaded, but that did not still fix the issue of things being clobbered.

When I have both gems installed and I run:

irb(main):001:0> require 'linkedin'
=> true
irb(main):002:0> ::LinkedIn::Client.new
NameError: uninitialized constant Api::QueryHelpers
        from /Users/me/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/linkedin-1.1.0/lib/linked_in/client.rb:8:in `<class:Client>'
irb(main):004:0> require 'linkedin-oauth2'                                                                                                                                                                                                    
=> true

But if I uninstall linkedin-oauth2 from my gemfile it works just fine:

irb(main):002:0> require 'linkedin'
=> true
irb(main):004:0> ::LinkedIn::Client.new
=> #<LinkedIn::Client:0x007f9eef6d72a8 @consumer_token=nil, @consumer_secret=nil, @consumer_options={}>

Why is that, especially since linkedin-oauth2 is not being required in the first example, yet the error occurs. Could it be because of how they require supporting files in the linkedin gem? Seems still like it shouldn't affect it.

like image 961
goddamnyouryan Avatar asked Nov 08 '22 10:11

goddamnyouryan


1 Answers

I wouldn't recommend doing this, since it could have some weird side effects such as if linkedin-oauth2 references itself with ::LinkedIn, but a method to redefine a ruby constant is shown in this answer.

I would change it a little bit to prevent renaming a constant warning... Object.send(:remove_const, :Stripe) instead of the Stripe = Module.new as shown in the answer. So, an example (not tested) would be:

require 'linkedin-oauth2'
LinkedInOauth2 = LinkedIn

Object.send(:remove_const, :LinkedIn)

require 'linkedin'
like image 59
Cody Gustafson Avatar answered Nov 09 '22 22:11

Cody Gustafson