diff options
author | John Crepezzi <seejohnrun@github.com> | 2019-07-23 15:55:48 -0400 |
---|---|---|
committer | John Crepezzi <seejohnrun@github.com> | 2019-07-24 16:31:24 -0400 |
commit | 396dba08741b2c1d5a41debbb4bbde799c9f2a31 (patch) | |
tree | a7e29cc3e0dfc322347f29678530e47ec2d1e708 /activerecord | |
parent | 9c913116c634fe5fe2159a94b8f1a244801a4877 (diff) | |
download | rails-396dba08741b2c1d5a41debbb4bbde799c9f2a31.tar.gz rails-396dba08741b2c1d5a41debbb4bbde799c9f2a31.tar.bz2 rails-396dba08741b2c1d5a41debbb4bbde799c9f2a31.zip |
Fix multiple database support for DATABASE_URL env variable
This commit fixes an issue where multi-database configurations were
incompatible with setting a `DATABASE_URL` environment variable.
As part of this work, this commit also includes a light refactor
to make both multi and single database configurations lead into the same
code path so they behave the same.
As mentioned in #36736, this regression was introduced as part of
f2ad69fe7a605b01bb7c37eeac6a9b4e7deb488e
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/lib/active_record/database_configurations.rb | 30 | ||||
-rw-r--r-- | activerecord/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb | 24 |
2 files changed, 42 insertions, 12 deletions
diff --git a/activerecord/lib/active_record/database_configurations.rb b/activerecord/lib/active_record/database_configurations.rb index bf31bb7c22..e122628b05 100644 --- a/activerecord/lib/active_record/database_configurations.rb +++ b/activerecord/lib/active_record/database_configurations.rb @@ -104,18 +104,28 @@ module ActiveRecord return configs.configurations if configs.is_a?(DatabaseConfigurations) return configs if configs.is_a?(Array) - build_db_config = configs.each_pair.flat_map do |env_name, config| - walk_configs(env_name.to_s, "primary", config) - end.flatten.compact + db_configs = configs.flat_map do |env_name, config| + if config.is_a?(Hash) && config.all? { |k, v| v.is_a?(Hash) } + walk_configs(env_name.to_s, config) + else + build_db_config_from_raw_config(env_name.to_s, "primary", config) + end + end.compact if url = ENV["DATABASE_URL"] - build_url_config(url, build_db_config) + merge_url_with_configs(url, db_configs) else - build_db_config + db_configs + end + end + + def walk_configs(env_name, config) + config.map do |spec_name, sub_config| + build_db_config_from_raw_config(env_name, spec_name.to_s, sub_config) end end - def walk_configs(env_name, spec_name, config) + def build_db_config_from_raw_config(env_name, spec_name, config) case config when String build_db_config_from_string(env_name, spec_name, config) @@ -141,16 +151,12 @@ module ActiveRecord config_without_url.delete "url" ActiveRecord::DatabaseConfigurations::UrlConfig.new(env_name, spec_name, url, config_without_url) - elsif config["database"] || config["adapter"] || ENV["DATABASE_URL"] - ActiveRecord::DatabaseConfigurations::HashConfig.new(env_name, spec_name, config) else - config.each_pair.map do |sub_spec_name, sub_config| - walk_configs(env_name, sub_spec_name, sub_config) - end + ActiveRecord::DatabaseConfigurations::HashConfig.new(env_name, spec_name, config) end end - def build_url_config(url, configs) + def merge_url_with_configs(url, configs) env = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call.to_s if configs.find(&:for_current_env?) diff --git a/activerecord/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb b/activerecord/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb index 6372abbf3f..15a045ed23 100644 --- a/activerecord/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +++ b/activerecord/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb @@ -323,6 +323,30 @@ module ActiveRecord assert_equal expected, actual end + + def test_tiered_configs_with_database_url + ENV["DATABASE_URL"] = "postgres://localhost/foo" + + config = { + "default_env" => { + "primary" => { "pool" => 5 }, + "animals" => { "pool" => 5 } + } + } + + expected = { + "adapter" => "postgresql", + "database" => "foo", + "host" => "localhost", + "pool" => 5 + } + + ["primary", "animals"].each do |spec_name| + configs = ActiveRecord::DatabaseConfigurations.new(config) + actual = configs.configs_for(env_name: "default_env", spec_name: spec_name).config + assert_equal expected, actual + end + end end end end |