17

只是出于好奇……在我之前的帖子Rails3.1 engine: can't get SLIM or HAML to work in test/dummy app我问在哪里告诉 Ruby 在我的test/dummy应用程序中使用一些 gem。

(显而易见的?)答案是将其放入我的引擎的 Gemfile 中。这行得通,但它让我有点不舒服,因为在 Yehuda Katz 的帖子澄清 .gemspec 和 Gemfile 的角色中,他提到......

...在开发 gem 时,Gemfile “gem 的 Gemfile 应该包含 Rubygems 源和单个 gemspec 行”。

另一方面,在我的 Engine 的 Gemfile(使用 Rails 生成rails plugin new my_engine)中有:

# jquery-rails is used by the dummy application
gem "jquery-rails"

所以这似乎是对的。更新:不,它没有!看看我下面的回答...

尽管如此,在 StackOverflow 上的其他地方,我看到解决方案据说只需要所需的 gem config/application.rb,而 https://stackoverflow.com/questions/5159607/rails-engine-gems-dependencies-how-to-load-them -into-the-application 它被告知最好放入lib/<your_engine>/engine.rb file.

这是我的想法:为什么test/dummy应用程序不简单地自动要求文件中指定的所有 Gems .gemspecadd_dependency我们甚至通过显式使用and来告诉 gem,哪些 gem 用于生产,哪些用于开发模式add_development_dependency,所以我看不出有什么不这样做的理由test/dummy

所以这是最后一个问题:我必须在哪里告诉 Ruby 在我的test/dummy应用程序中使用 gem?我不想强迫 Ruby 在主机应用程序中也使用宝石。

4

3 回答 3

5

我认为正确的方法如下:

引擎是一个普通的宝石。开发 gem 时,将其依赖项放入gemspec文件中。如果您使用捆绑软件,那么作为开发人员,您可以创建一个.lock没有问题的特定版本的文件。但是在 中声明依赖项gemspec并不足以使用它们,您必须require在 gem 代码中使用它们。需要时,如果 gem 与 bundle 一起使用,则.lock使用版本。

在引擎中,与任何其他 gem 一样,它是相同的。您在gemspec文件中定义依赖项并运行bundle install,但仅使用它们是不够的。您必须要求它们,例如,在lib/my_engine.rb.

例如:

# File: my_engine.rspec
# ...
s.add_dependency `slim_rails`, ' ~>1.0'

# ...

# File: lib/my_engine.rb
require "my_engine/engine"
require "slim-rails"

module MyEngine
end

Gemfile我不确定为什么如果.

引擎内的 Gem 依赖项应在引擎根目录的 .gemspec 文件中指定。原因是引擎可能作为 gem 安装。如果要在 Gemfile 中指定依赖项,传统的 gem 安装将无法识别这些依赖项,因此它们不会被安装,从而导致引擎出现故障。

于 2013-07-27T10:43:35.957 回答
2

这是我到目前为止发现的。

在引擎(使用创建)中,您必须rails plugin new my_engine在 my_engine.gemspec 文件中指定所需的 gem ,因为它们随后会从 test/dummy/Gemfile 中使用.gemspec

这是生成的 test/dummy/Gemfile 内容:

source "http://rubygems.org"

# Declare your gem's dependencies in simple_view_helpers.gemspec.
# Bundler will treat runtime dependencies like base dependencies, and
# development dependencies will be added by default to the :development group.
gemspec

# jquery-rails is used by the dummy application
gem "jquery-rails"

# Declare any dependencies that are still in development here instead of in
# your gemspec. These might include edge Rails or gems from your path or
# Git. Remember to move these dependencies to your gemspec before releasing
# your gem to rubygems.org.

# To use debugger
# gem 'debugger'

我真的不知道这条线gem "jquery-rails"在这里做什么,似乎与评论中提出的完全矛盾。另一方面,当我尝试在我的测试/虚拟应用程序中使用SLIM gem(而不是 ERB)时,似乎我必须在 Gemfile 中指定它,否则它将无法工作。还是有点乱,这玩意...

于 2012-09-27T13:41:55.540 回答
2

TL;博士:

Gemfile开发引擎时不要使用任何。把所有东西都放在你的引擎里gemspec,让引擎本身需要它需要的一切。


为什么测试/虚拟应用程序不简单地自动要求 .gemspec 文件中指定的所有 Gem?

我猜应用程序不会出于性能原因自动要求其引擎的依赖项。

因此,如果虚拟应用程序应该是使用引擎对真实应用程序的真实模拟,那么它也不应该这样做。

此外,假设虚拟应用程序自动要求所有依赖项,包括开发依赖项。在这种情况下,即使您的开发依赖项之一实际上是运行时依赖项,您的测试也可能会成功。那真的很烦人。

据说只需要 config/application.rb 中所需的 gem

这也可能掩盖引擎的运行时依赖关系,所以最好不要这样做。

所以这是最后一个问题:我必须在哪里告诉 Ruby 在我的测试/虚拟应用程序中使用 gem?我不想强迫 ruby​​ 在主机应用程序中也使用 gem。

如果该 gem 仅用于测试,请在您的测试/规范助手中使用它。

否则,如果您的引擎需要该 gem 才能运行,您确实应该强制使用它。

James:这会让我相信引擎的依赖项放在 gemspec 中,而虚拟应用程序的依赖项放在 Gemfile 中

虚拟应用程序的捆绑程序存根实际上引用了虚拟应用程序自己的缺失 Gemfile。所以我想它是故意遗漏的。这是完全有道理的。

可以这样想:您为更改虚拟应用程序所做的任何事情都会导致测试无法在中性背景下执行,因此不具有代表性。

如果您真的希望能够重用您的引擎,并将其放入任何空白的新 Rails 应用程序中,那么您的虚拟应用程序应该就是这样:一个空白的新 Rails 应用程序。

于 2015-11-23T18:30:58.117 回答