【问题标题】:Using rails inside gem as a dependency在 gem 中使用 rails 作为依赖项
【发布时间】: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 应用程序中。)

【问题讨论】:

    标签: ruby-on-rails gem activeadmin gemfile


    【解决方案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.1v3.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 库 最后一点下。
    • 正确。那你的问题是什么?
    • 更新问题以合并您的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-24
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 2013-04-14
    相关资源
    最近更新 更多