在 gem 中使用 rails 作为依赖项
Posted
技术标签:
【中文标题】在 gem 中使用 rails 作为依赖项【英文标题】:Using rails inside gem as a dependency 【发布时间】:2013-09-04 05:33:19 【问题描述】:在浏览active-admin 代码时,我发现Gemfile 包含rails 条目。
rails_version = detect_rails_version
gem 'rails', rails_version
这是否意味着 active-admin 在内部创建了一个不是主要 rails 应用程序的 rails 服务器?
如果是,这是否会导致性能问题并且将其用于复杂的 Rails 应用程序是一种不好的做法?
如果否,在active-admin Gemfile中有什么用?
用不同的关键字搜索了很多,这只会导致 gem 安装和相关结果。
如果有人提出一些见解,我会很高兴。 谢谢:)
更新1: 在 Gaurish 回答和googling 之后,似乎 gem 中的 Gemfile 用于在内部列出 gem 所需的依赖项。 但它产生了另一个问题,当应用程序 gem 和 gem 的 gem 冲突时会发生什么?
更新2:
我们可以独立使用 active-admin,因为它有 rails 作为依赖项吗? (只需通过gem install active-admin
安装active-admin,而不是将其保存在其他rails 应用程序中。)
【问题讨论】:
【参考方案1】:没有。这似乎是一个捆绑程序问题。 this code 只是声明了对 rails 的依赖。声音很奇怪?这就是我认为正在发生的事情。
通常的方法是使用以下行在.gemspec
文件中声明您的依赖项:
s.add_dependency("rails", ">= 3.0.0")
以上几行添加了对 rails v3.0
& above(v3.1
,v3.2
) 的依赖。现在这适用于其他 gem & bundler 将自动解决依赖关系。但是当您尝试支持多个版本的 rails 时,bundler 可能会感到困惑。
理想情况下,bundler 应该能够自动捆绑(安装)我们 gem 的所有依赖项。还有 gem 依赖的依赖。例如,bundle 应该足够聪明,可以判断是否需要 rails v3.1
或 v3.2
,它还需要包含 sass-rails
和 'uglifier',因为它们是 rails 3.1 和 3.2 所要求的。但如果需要 rails v3.0
,则无需进行任何额外操作。
但我们生活在不太完美的世界里,所以 bundler 不够聪明。因此,我认为这就是 active-admin
不得不针对 bundler 的缺点采取以下技巧的原因。
unless defined?(RAILS_VERSION_FILE)
RAILS_VERSION_FILE = File.expand_path("../../../.rails-version", __FILE__)
end
unless defined?(DEFAULT_RAILS_VERSION)
DEFAULT_RAILS_VERSION = "3.1.0"
end
def detect_rails_version
return DEFAULT_RAILS_VERSION unless File.exists?(RAILS_VERSION_FILE)
File.read(RAILS_VERSION_FILE).chomp
end
def write_rails_version(version)
File.open(RAILS_VERSION_FILE, "w+")|f| f << version
end
rails_version = detect_rails_version
gem 'rails', rails_version
case rails_version
when /^3\.0/
# Do nothing, bundler should figure it out
when /^3\.(1|2)/
# These are the gems you have to have for Rails 3.1 to be happy
gem 'sass-rails'
gem 'uglifier'
else
raise "Rails #rails_version is not supported yet"
end
如果您注意到上面的代码,它会检查当前版本的 rails 是 v3.1 还是 v3.2。如果是,则添加新的两个作为依赖项。这就是这段代码所做的一切。
[更新]
问题 1. 当应用程序 gem 和 gem 的 gem 冲突时会发生什么? 如果它们以这样的方式发生冲突,以至于捆绑器无法找到满足您的应用程序和 gem 的依赖关系的兼容版本。 bundler 将失败并出现类似以下的错误:
Bundler could not find compatible versions for gem "json":
In Gemfile:
chef (~> 10.26) ruby depends on
json (<= 1.7.7, >= 1.4.4) ruby
berkshelf (~> 2.0) ruby depends on
json (1.8.0)
问题 2。我们可以单独使用 active-admin 吗
没有铁轨?不,当您执行gem install active-admin
时,rubygems 将自动安装 rails,因为它在 gemspec
文件中列为此 gem 的依赖项。
【讨论】:
感谢您的宝贵时间,但您认为,为什么 Gemfile 会包含对其他宝石(如波旁威士忌)的引用,而普通的 Rails 应用程序中并不需要这些引用? 一般来说,gem 的 Gemfile 应该包含 Rubygems 源代码和一个 gemspec 行,但开发人员有时不遵循这个建议。这就是我们在这里看到的。见yehudakatz.com/2010/12/16/… 是的,没错。但是在 gem 开发中,Gemfile 用于编写 gem 内部使用的 gems 依赖项。 yahuda 在 Ruby 库 最后一点下。 正确。那你的问题是什么? 更新问题以合并您的答案。以上是关于在 gem 中使用 rails 作为依赖项的主要内容,如果未能解决你的问题,请参考以下文章