我正在创建一个Rails Web应用程序,它使用一个共享的模型库(作为Rails引擎),存储在一个子库(Git子树)中。这个共享库包含对其他Ruby gem的依赖(在我的例子中,HTTParty和Dalli),其中我希望由包含此共享库的父项目自动引用。
但是,我的gem的依赖项似乎没有在父项目中解析,当我启动我的Web应用程序时,它缺少对共享库中这些gem依赖项的引用。 (即NameError: uninitialized constant ApiClient::HTTParty
)如果我明确地将这些引用添加到我的Web应用程序的Gemfile中(如取消注释下面的Gemfile行),一切正常。
如何将这些依赖项变为“链”,让父项目自动解析这些引用?
这是我的项目的样子:
[MyRailsApp]
-- ...
-- [app]
-- [config]
-- [lib]
-- [MyLib]
-- ...
-- [app]
-- [config]
-- [lib]
-- [MyLib]
-- version.rb
-- engine.rb
-- MyLib.gemspec
-- Gemfile
-- Gemfile
MyRailsApp / Gemfile中:
source 'https://rubygems.org'
gem 'activesupport', '3.2.13', :require => 'active_support'
gem 'actionpack', '3.2.13', :require => 'action_pack'
gem 'actionmailer', '3.2.13', :require => 'action_mailer'
gem 'railties', '3.2.13', :require => 'rails'
...
# gem 'dalli'
# gem 'httparty'
gem 'MyLib', :path => 'lib/MyLib'
MyLib中/ MyLib.gemspec :
$:.push File.expand_path("../lib", __FILE__)
# Maintain your gem's version:
require "mylib/version"
# Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
s.name = "MyLib"
s.version = MyLib::VERSION
s.authors = ["David"]
s.email = ["ops@myemail.com"]
s.homepage = "http://www.mysite.com"
s.summary = "Shared Library"
s.description = "Shared Library"
s.files = Dir["{app,config,db,lib}/**/*"] + ["MIT-LICENSE", "Rakefile", "README.rdoc"]
s.add_dependency "rails", "~> 3.2.13"
s.add_dependency "dalli", ">= 2.6.4"
s.add_dependency "httparty", ">= 0.11.0"
end
答案 0 :(得分:2)
想出来。我有错误的想法...我认为用于安装gem依赖项(工作正常)的Gemspecs也将被Rails用来确定在应用程序启动时需要将哪些依赖项加载到内存中。至少在使用Rails引擎时不是这种情况。
对于普通的gem,看起来典型的Rails Web应用程序在boot.rb文件中有一行,它在应用程序Gemfile中加载所有gem和依赖项。但是,此自动加载似乎不会扩展到Gemfile中列出的Rails引擎。在这种情况下,您必须手动将依赖项加载到应用程序内存中,方法是找到engine.rb
文件(在Rails引擎中)并在文件开头添加require 'yourgem'
。这将在引擎加载时加载依赖关系。
如果这个解释不充分,一位朋友找到并链接了我这个相关的问题/答案: https://stackoverflow.com/a/5850503
答案 1 :(得分:1)
如果您希望rubygems了解您的依赖项,请使用正确的.gemspec
文件打包它们。您不必发布您的gem,它可以是私有的,并通过git://
类型的URL引用。
问题是,通常你的.gemspec
需要处于根级别。你不能把它埋在你的项目中,因为Rubygems不会一直不去寻找它们。
在您的用例中,MyLib
应该是一个单独的东西。