为什么我的rails应用程序会在控制台启动时忽略env var DATABASE_URL?

时间:2014-07-29 08:57:33

标签: ruby-on-rails postgresql activerecord ruby-on-rails-3.2

TL; DR:

$ export DATABASE_URL=postgres://user:pwd@localhost:5432/new_db
$ RAILS_ENV=test bundle exec rails c
[1] pry(main)> ActiveRecord::Base.connection.current_database
=> "test"
[2] pry(main)> ActiveRecord::Base.establish_connection;nil
=> nil
[3] pry(main)> ActiveRecord::Base.connection.current_database
=> "new_db"
[4] pry(main)> # WTF ?!?

背景:我们目前正在托管多个工作来构建,测试和推送到我们的DEV和QA环境。由于我们在database.yml文件中具有相同的测试配置,因此当两个env同时进行测试时,我们最终都会失败测试,​​因此我们决定使用两个数据库。

我们正在尝试:为了实现这一目标(使用几个与同一个database.yml文件相同的数据库),我们决定将DATABASE_URL环境变量的值设置为< postgres:/ /用户:PWD @本地:5432 / new_db'

问题是什么:当我们在控制台中手动运行establish_connection时,似乎只使用了DATABASE_URL的值。奇怪的是,运行rake会对正确的db(new_db)产生影响。

Rails版本是3.2.19

有没有办法正确覆盖该环境变量?

非常感谢提前!

3 个答案:

答案 0 :(得分:2)

如果您仍然遇到Rails 4.2的这个问题,请先尝试使用spring stop停止弹簧。 Spring会在重新启动时接受新的ENV变量。

答案 1 :(得分:1)

配置/初始化程序中有一个文件可以执行此操作:

Rails.application.config.after_initialize do
  ActiveRecord::Base.connection_pool.disconnect!

  ActiveSupport.on_load(:active_record) do
    config = Rails.application.config.database_configuration[Rails.env]
    config['reaping_frequency'] = ENV['DB_REAP_FREQ'] || 10 # seconds
    config['pool']              = ENV['DB_POOL'] || 5
    ActiveRecord::Base.establish_connection(config)
  end
end

此文件说明:始终从database.yml加载配置,并添加两个参数reaing_frequencypool

将初始化程序更改为此可解决问题:

Rails.application.config.after_initialize do
  ActiveRecord::Base.connection_pool.disconnect!

  ActiveSupport.on_load(:active_record) do
    if !ENV['DATABASE_URL']
      config = Rails.application.config.database_configuration[Rails.env]
      config['reaping_frequency'] = ENV['DB_REAP_FREQ'] || 10 # seconds
      config['pool'] = ENV['DB_POOL'] || 5
      ActiveRecord::Base.establish_connection(config)
    else
      ActiveRecord::Base.establish_connection
    end
  end
end

注意:默认的rails行为是先在ENV['DATABASE_URL']然后在config/database.yml中搜索配置。因此,如果您只是删除初始化程序,那也可以解决问题。

答案 2 :(得分:0)

我也遇到过与Rails 4.2类似的问题。除了@ mario-uher关于停止弹簧的评论之外,还有一件事要记住。我一直在我的初始化程序中访问数据库配置,如下所示:

Rails.application.configure do |app|
  app.config.database_configuration[Rails.env]
end

这样做会从 database.yml 返回设置。实际的合并魔法发生在ActiveRecord本身。所以应该像这样访问合并的配置:

ActiveRecord::Base.configurations[Rails.env]