【问题标题】:Multiple environments for Ruby applicationRuby 应用程序的多种环境
【发布时间】:2015-07-07 14:38:54
【问题描述】:

我一直在编写 Rails 应用程序,以至于我突然被 Rails 免费提供的东西卡住了:环境。

也就是说,您可以在本地运行 Rails 应用程序,默认情况下,RAILS_ENV(或 Rails.env)是“开发”。如果您正在运行规范/测试,它就是“测试”,当您部署到生产服务器时,您将其设置为“生产”运行。

当您有配置文件时,这特别有用。也可用于 Gemfile 以区分特定环境的 gem。

所以现在我的问题是:我正在编写一个纯 Ruby 应用程序,但我不知道设置它以便我仍然可以拥有多个环境的最佳方法?我想为第 3 方服务(如 MongoLab/Iron.IO/等)设置配置文件,但我希望它们设置为“开发”、“测试”、“生产”等。然后我想成为能够从各种环境中运行应用程序。

我知道我可以通过命令行环境变量手动处理它,但我想知道是否有最好的(更好的?)实践?有什么宝石可以帮助解决这个问题吗?或者关于如何为纯 Ruby 应用构建环境处理的任何建议?

谢谢,

【问题讨论】:

标签: ruby-on-rails ruby configuration environment-variables


【解决方案1】:

使用ENV['RACK_ENV']RAILS_ENV 实际上只是它的一个副本。

使用其他 ENV 来管理您的依赖项。例如,凭证和配置可以存储在 ENV 中。

一些 ENV 通常存储在配置文件中,例如 database.ymlmongoid.yml

您可以使用dotenv gem 来管理您本地的 ENV。但是,我更喜欢使用 Ruby 或 shell 脚本来设置 ENV 和/或在开发环境中启动服务器:

local_setup.rb:

ENV[ 'RACK_ENV' ] = 'development'

rackup_local.sh:

RACK_ENV=development rackup

您可以为测试配置使用类似的脚本,并在规范助手中要求它。我更喜欢将配置添加到规范助手的顶部。

如果你在你的 env 脚本中加入了秘密,请确保 Git 忽略它并且不要将它添加到你的 repo 中。

关于 Gemfile,除非有充分的理由,否则在不同的环境中使用不同的 gem 并不是一个好主意。测试、调试和缓存是在 Gemfile 中的环境组中的好例子。

【讨论】:

  • 为什么在 Gemfile 中使用组不是一个好主意?
  • 因为它引入了生产环境和测试环境之间的差异。它会降低测试的效率。
  • 那些专门用于测试或调试但在生产中没有位置的 gem 呢?或者解决生产特定问题(例如缓存)但会使测试变得困难的 gem...
  • 是的,这些应该在 Gemfile 中的相应组中。
  • 但是你说我们不能使用组。
【解决方案2】:

如果您只是在谈论配置文件,您可以使用类似于 Rail 的 database.yml 文件的设置,将其读入并选择“正确”的变量集。

至少还有one gem来处理这种“多级”的配置文件。

【讨论】:

    【解决方案3】:

    你可以像 rails 那样做一些事情:

    class AppEnvironment
    
        def initialize(env = :production)
          @name = env.intern
        end
    
        def development?
            @name == :development
        end 
    
        def test?
            @name == :test
        end
    
        def production?
            @name == :production
        end
    end
    
    app_environment = AppEnvironment.new( ENV['APP_ENVIRONMENT'] )
    

    然后你通过 rake 任务设置环境变量。

    namespace :myapp do
      desc "Run a development server"
      task :server => :environment do
        ENV['APP_ENVIRONMENT'] ||= "development"
        # ...
      end
    
      desc "Run a bunch of tests"
      task :test => :environment do
        ENV['APP_ENVIRONMENT'] ||= "test"
        # alternatively do this in `spec_helper.rb`
      end
    
    end
    

    已添加。

    使用 Bundler 非常容易在每个环境中使用不同的 gem。

    您可能会从 rails 中的 config/application.rb 认出这一行:

    Bundler.require(:default, Rails.env) # Rails.env is just a string
    

    这告诉 bundler 到 require all gems in a specific group 除了在组外声明的 gems。

    gem 'foo'
    
    group :test do
      gem 'rspec'
    end
    

    【讨论】:

    • 另外有趣的阅读为什么你不应该使用ENV['RACK_ENV']hezmatt.org/~mpalmer/blog/2013/10/13/…
    • 我喜欢这种方法。我最终使用了一种改进的方法。看看 Rails 在内部是如何做到这一点的也很有趣。当然,我不需要以下语法糖:Rails.env.development?我很满意:Helper.env == "development"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-24
    • 1970-01-01
    • 2011-07-30
    • 2019-07-20
    • 1970-01-01
    相关资源
    最近更新 更多