ruby-on-rails - 在运行时在 Rails 3 中加载 gem

标签 ruby-on-rails ruby ruby-on-rails-3 rubygems bundler

我有 Rails 3.0.x 应用程序。我想在运行时加载 gem,而不使用 Gemfile

我想要完成的是像往常一样加载我的应用程序,Bundler 加载常规 gem。之后我想加载位于特定目录中的所有 gem (Rails 引擎)(但直到运行时,我不知道那是什么 gem )。

有谁知道这在 Rails 中是否可行,也许使用 Bundler API?

最佳答案

您正在尝试做的事情很危险。如果您的每个 Rails 引擎也是 gems - 那么它们也会有带有其他依赖项的 Gemfiles,而这些又会有其他依赖项,等等。如果您允许 Bundler 解决这些问题,那么您在运行时的问题就会减少。

下面是您将如何不使用任何 hack 来做到这一点。请记住,您的 Gemfile只是 Ruby 代码,您可以拥有默认不加载的 gem。

# In your Gemfile, add at the end:
Dir[YOUR_RAILS_ENGINES_SUBFOLDER + "/*/*.gemspec"].each do |gemspec_file|
  dir_name = File.dirname(gemspec_file)
  gem_name = File.basename(gemspec_file, File.extname(gemspec_file))

  # sometimes "-" and "_" are used interchangeably in gems
  # for e.g. gemspec_file is "engines/my-engine/my_engine.gemspec"
  #   dir_name will be engines/my-engine
  #   gem_name will be my_engine

  # Register that engine as a dependency, *without* being required
  gem gem_name, :path => dir_name, :require => false

  # e.g. this is similar to saying
  #  gem 'my_engine', :path => 'engines/my-engine', :require => false
end

现在您已将所有动态 Rails 引擎注册为 gem 依赖项。 Bundler 将解决它们,以及它们所有的子依赖关系,因此您不必担心任何事情。只需运行 bundle install在运行应用程序之前,或者每当您在该文件夹中添加/删除任何引擎时。

好的是,这些 gem 只是被注册,而不是加载。因此,在您的生产代码中,您现在可以通过说出 require <your-engine-name> 来加载您在运行时选择的任何 gem。

编辑:额外的代码注释

关于ruby-on-rails - 在运行时在 Rails 3 中加载 gem,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8492547/

相关文章:

sql - 将数组传递给 Rails where 方法

ruby-on-rails - 如何连接两个事件记录结果以返回可以进一步过滤的新结果?

ruby - 如何访问 rspec 中的描述文本

ruby-on-rails - database.yml 代理?或等效的?

ruby-on-rails - 将操作关联到 Rails 中 form.select 的 on_change?

ruby-on-rails - 无法运行 node_modules/.bin/browserifyinc。确保你已经使用 npm 安装它

ruby-on-rails - 在 Rails 中支持时区

ruby - 当 bundler 包含来自源代码的 gem 时,如何使用 native 扩展测试 gem?

ruby-on-rails - 如何在 Ruby on Rails 中创建项目范围内可用的 javascript 函数?

windows - 在 Rails 3 中使用回形针裁剪照片时遇到错误