11

我有一个 Rails 3 应用程序,我正在将其变成 Rails 引擎/gem。这个引擎有一些我放在它的 .gemspec 文件中的 gem 依赖项。

我创建了一个新的“父”Rails 3 应用程序,我想将我的引擎 gem 添加到 Gemfile 并自动“加载”gem 的依赖项,但这对我不起作用!bundle install安装 gem 依赖项很好,但是当我启动服务器时,应用程序崩溃,因为它们没有加载。

例如,我的引擎的 gemspec 包含以下几行:

s.add_runtime_dependency(%q<rails>, ["= 3.0.7"])
s.add_runtime_dependency(%q<acts_as_commentable>, [">= 3.0.1"])
s.add_runtime_dependency(%q<haml>, [">= 3.1.1"])

.. 并且父 Rails 3 应用程序在其 Gemfile 中有这些行:

source 'http://rubygems.org'

gem 'my_engine', :path => "~/src/gems/my_engine"

但我收到以下错误:

undefined local variable or method `acts_as_commentable'
from /home/user/src/gems/my_engine/app/models/account.rb:66:in `<class:Account>'

但是,如果我添加gem 'acts_as_commentable', '>= 3.0.1'到父 Rails 3 应用程序的 Gemfile 中,则加载 gem 并且错误消失。

我正在使用 Rails 3.0.8。

有没有人有什么建议?我是否需要更改引擎的加载方式?

4

4 回答 4

12

在 Rails 主应用程序启动期间,Bundler 将只需要 Gemfile 中直接列出的依赖项,而不需要任何子依赖项。当它本身被需要时,需要它的依赖项是你的库/引擎的责任。您可以使用 Railtie 中的初始化程序来执行此操作。

class MyRailtie < Rails::Railtie
  initializer "require stuff" do
    require "stuff"
  end
end
于 2011-08-07T12:46:53.533 回答
3

在我们的 Rails 引擎中,我们使用了一个小技巧来自动请求依赖项。不幸的是,您无法指定它们是否应加载到 .gemspec 中,这将允许更大的控制。

Gem.loaded_specs["our_rails_engine"].dependencies.each do |d|
  begin
    require d.name
  rescue LoadError => le
    # Put exceptions here.
    raise le if d.name !~ /factory_girl_rails/
  end
end
于 2014-01-22T20:16:14.633 回答
2

我在看 Spree(Rails Engines 的超级英雄!),他们这样做spree_core-0.60.1/lib/spree_core.rb

require "rails/all"

require 'state_machine'
require 'paperclip'
require 'stringex'
require 'will_paginate'
require 'nested_set'
require 'acts_as_list'
require 'resource_controller'
require 'active_merchant'
require "meta_search"
require "find_by_param"

所以答案是,在你的 gem 中,你必须一个一个地要求它的所有 gem 依赖项。好吧,这就是我现在要做的。但是,如果这在未来发生变化,请发表评论。

于 2011-08-06T08:19:38.037 回答
1

似乎它不起作用,我用rails 3引擎创建了一个宿主项目和一个子项目。

将 gem 添加到引擎的 gemspec

s.add_dependency 'simple_form'

然后将要求添加到engine_name.rb,如下所示

require 'simple_form'

但是如果删除宿主项目的 Gemfile 中的 [gem 'simple_form'] 行,它会立即显示 undefined

于 2011-12-02T11:03:11.707 回答