如何设置gem依赖项而不必在使用它的Gemfile上声明它们?

时间:2012-02-29 18:40:16

标签: ruby-on-rails gem

我正在本地构建一个gem,假设它的名字是“MyGem”。

现在假设MyGem依赖于其他已经构建的gem,例如“cancan”。

所以,我在mygem.gemspec中添加了一行:

add_runtime_dependency("cancan")

问题在于:如果我将MyGem安装到一个新项目中,方法是将它添加到我的gemfile中,如下所示:

gem "mygem", :path => "path/to/my/local/gem"

然后这个新项目无法使用cancan方法,我必须在新项目gemfile上明确声明cancan才能使用它。

我也试过使用gemspec方法,但也没有解决我的问题。 有什么想法吗?

更新

我只是想补充一点,当我只在我的新应用程序gemfile中声明myGem时,在运行bundle install后,所有依赖项都已安装。 也就是说,如果我运行gem list,则显示“cancan”gem,但我仍然无法从应用程序级别访问它。

感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

好的,我已经解决了这个问题。我不确定这是否是最佳解决方案,但确实有效。

让应用程序级开发人员明确地在他的gemfile中添加依赖项没有任何意义。因此,正在安装宝石时,我只需要在我的my_engine.rb文件里面我的宝石中的所有宝石依赖项。

按照示例,在我的my_engine.rb中添加了以下行

require "cancan"

那就是...... 你可以做得更好:

autoload :CanCan, "cancan"

因此只有在调用模块时才会加载模块。 甚至比这更好,你只能加载你正在使用的cancan文件(也许你不需要加载所有文件)。

如果您使用引擎,可以在my_gem.rb文件或engine.rb文件中添加该行。

这对我有用,我希望这有助于某人。

答案 1 :(得分:0)

使用add_dependency而不是add_runtime_dependency(这可能对cancan有帮助)然后在新项目上运行bundle update。

答案 2 :(得分:0)

“cancan”宝石名称是否与要求的名称相匹配?

yajl-ruby gem的例子:

Gem::Specification.new do |s|
  s.name = %q{yajl-ruby}
...

但是当需要图书馆时,你会使用不同的字符串:

require 'yajl'

这意味着在你的Gemfile中,你必须明确要求依赖(你说你想避免)。

gem 'yajl-ruby', '>=1.0', :require => 'yajl'

为避免需要这样做,并且如果您是“cancan”依赖项的作者,则应该使gem名称与require名称匹配。

我能想到的唯一选择是直接在你的一个源文件中使用依赖项(就像你在解决方案中所做的那样)。