Ruby on rails 在Rails的同一命名空间中使用两个gem
我有一个使用gem的应用程序,但我需要使用LinkedIn OAuth2实现,这是一个很好的例子 我需要在初始gem中为现有用户支持oAuth1上的请求,但我需要为将来的新用户支持OAuth2 问题是,这两个gem都使用Ruby on rails 在Rails的同一命名空间中使用两个gem,ruby-on-rails,ruby,ruby-on-rails-5,Ruby On Rails,Ruby,Ruby On Rails 5,我有一个使用gem的应用程序,但我需要使用LinkedIn OAuth2实现,这是一个很好的例子 我需要在初始gem中为现有用户支持oAuth1上的请求,但我需要为将来的新用户支持OAuth2 问题是,这两个gem都使用LinkedIn名称空间作为其模块名,并且根据我在gem文件中包含它们的顺序,一个会影响另一个 我尝试向GEM文件添加require:false,如下所示: gem 'linkedin', require: false gem 'linkedin-oauth2', require
LinkedIn
名称空间作为其模块名,并且根据我在gem文件中包含它们的顺序,一个会影响另一个
我尝试向GEM文件添加require:false
,如下所示:
gem 'linkedin', require: false
gem 'linkedin-oauth2', require: false
但奇怪的是,当我转到控制台时,仍然需要第一个控制台,而第二个控制台则不需要:
irb(main):001:0> require 'linkedin'
=> false
irb(main):002:0> require 'linkedin-oauth2'
=> true
这与require的工作原理有关吗?有没有可能只在单独的lib文件中加载这些gem中的一个,而不互相碰撞
编辑
我发现我需要在我的一个规范文件中使用linkedin
,这导致它被自动加载,但这并不能解决问题
当我安装了两个gems并运行时:
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
为什么会这样,特别是因为第一个示例中不需要linkedin-oauth2,但出现了错误。这可能是因为他们在
linkedin
gem中的表现吗?似乎它仍然不应该影响它。我不建议这样做,因为它可能会有一些奇怪的副作用,例如如果linkedin-oauth2使用::linkedin
引用自己,但是中显示了一种重新定义ruby常量的方法
我会稍微更改它,以防止重命名一个持续的警告Object.send(:remove_const,:Stripe)
而不是Stripe=Module.new
,如答案所示。因此,一个示例(未测试)是:
require 'linkedin-oauth2'
LinkedInOauth2 = LinkedIn
Object.send(:remove_const, :LinkedIn)
require 'linkedin'
您可以将所有内容移动到使用
linkedin-oauth2
gem,或者修补gem模块本身,以便第一个模块只是扩展第二个模块(但不建议这样做,因为它仍然会破坏命名相同的方法)。“第一个模块仍然是必需的”–你确定你不需要其他地方的吗?@Stefan说得对。在我的一个规格中,我仍然需要它。所以我修正了这个问题,但是现在当我需要“linkedin”时,它似乎需要linkedin-oauth2
gem。@Stefan我编辑了这个问题,并添加了关于我看到的问题的更多细节。
require 'linkedin-oauth2'
LinkedInOauth2 = LinkedIn
Object.send(:remove_const, :LinkedIn)
require 'linkedin'