Skip to content

Commit

Permalink
Merge pull request #35242 from eileencodes/add-setter-and-deprecation…
Browse files Browse the repository at this point in the history
…-for-configurations-hashes

Add setter and deprecation for configurations hashes
  • Loading branch information
eileencodes committed Feb 14, 2019
2 parents e53430f + 06f9434 commit 5f71806
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 49 deletions.
30 changes: 24 additions & 6 deletions activerecord/lib/active_record/database_configurations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ def env_with_configs(env = nil)

def build_configs(configs)
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)
Expand Down Expand Up @@ -166,21 +167,38 @@ def build_url_config(url, configs)
end

def method_missing(method, *args, &blk)
if Hash.method_defined?(method)
ActiveSupport::Deprecation.warn \
"Returning a hash from ActiveRecord::Base.configurations is deprecated. Therefore calling `#{method}` on the hash is also deprecated. Please switch to using the `configs_for` method instead to collect and iterate over database configurations."
end

case method
when :each, :first
throw_getter_deprecation(method)
configurations.send(method, *args, &blk)
when :fetch
throw_getter_deprecation(method)
configs_for(env_name: args.first)
when :values
throw_getter_deprecation(method)
configurations.map(&:config)
when :[]=
throw_setter_deprecation(method)

env_name = args[0]
config = args[1]

remaining_configs = configurations.reject { |db_config| db_config.env_name == env_name }
new_config = build_configs(env_name => config)
new_configs = remaining_configs + new_config

ActiveRecord::Base.configurations = new_configs
else
super
raise NotImplementedError, "`ActiveRecord::Base.configurations` in Rails 6 now returns an object instead of a hash. The #{method} method is not supported. Please use `configs_for` or consult the documentation for supported methods."
end
end

def throw_setter_deprecation(method)
ActiveSupport::Deprecation.warn("Setting `ActiveRecord::Base.configurations` with `#{method}` is deprecated. Use `ActiveRecord::Base.configurations=` directly to set the configurations instead.")
end

def throw_getter_deprecation(method)
ActiveSupport::Deprecation.warn("`ActiveRecord::Base.configurations` no longer returns a hash. Methods that act on the hash like `#{method}` are deprecated and will be removed in Rails 6.1. Use the `configs_for` method to collect and iterate over the database configurations.")
end
end
end
117 changes: 117 additions & 0 deletions activerecord/test/cases/database_configurations_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# frozen_string_literal: true

require "cases/helper"

class DatabaseConfigurationsTest < ActiveRecord::TestCase
unless in_memory_db?
def test_empty_returns_true_when_db_configs_are_empty
old_config = ActiveRecord::Base.configurations
config = {}

ActiveRecord::Base.configurations = config

assert_predicate ActiveRecord::Base.configurations, :empty?
assert_predicate ActiveRecord::Base.configurations, :blank?
ensure
ActiveRecord::Base.configurations = old_config
ActiveRecord::Base.establish_connection :arunit
end
end

def test_configs_for_getter_with_env_name
configs = ActiveRecord::Base.configurations.configs_for(env_name: "arunit")

assert_equal 1, configs.size
assert_equal ["arunit"], configs.map(&:env_name)
end

def test_configs_for_getter_with_env_and_spec_name
config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", spec_name: "primary")

assert_equal "arunit", config.env_name
assert_equal "primary", config.spec_name
end

def test_default_hash_returns_config_hash_from_default_env
original_rails_env = ENV["RAILS_ENV"]
ENV["RAILS_ENV"] = "arunit"

assert_equal ActiveRecord::Base.configurations.configs_for(env_name: "arunit", spec_name: "primary").config, ActiveRecord::Base.configurations.default_hash
ensure
ENV["RAILS_ENV"] = original_rails_env
end

def test_find_db_config_returns_a_db_config_object_for_the_given_env
config = ActiveRecord::Base.configurations.find_db_config("arunit2")

assert_equal "arunit2", config.env_name
assert_equal "primary", config.spec_name
end

def test_to_h_turns_db_config_object_back_into_a_hash
configs = ActiveRecord::Base.configurations
assert_equal "ActiveRecord::DatabaseConfigurations", configs.class.name
assert_equal "Hash", configs.to_h.class.name
assert_equal ["arunit", "arunit2", "arunit_without_prepared_statements"], ActiveRecord::Base.configurations.to_h.keys.sort
end
end

class LegacyDatabaseConfigurationsTest < ActiveRecord::TestCase
unless in_memory_db?
def test_setting_configurations_hash
old_config = ActiveRecord::Base.configurations
config = { "adapter" => "sqlite3" }

assert_deprecated do
ActiveRecord::Base.configurations["readonly"] = config
end

assert_equal ["arunit", "arunit2", "arunit_without_prepared_statements", "readonly"], ActiveRecord::Base.configurations.configs_for.map(&:env_name).sort
ensure
ActiveRecord::Base.configurations = old_config
ActiveRecord::Base.establish_connection :arunit
end
end

def test_can_turn_configurations_into_a_hash
assert ActiveRecord::Base.configurations.to_h.is_a?(Hash), "expected to be a hash but was not."
assert_equal ["arunit", "arunit2", "arunit_without_prepared_statements"].sort, ActiveRecord::Base.configurations.to_h.keys.sort
end

def test_each_is_deprecated
assert_deprecated do
ActiveRecord::Base.configurations.each do |db_config|
assert_equal "primary", db_config.spec_name
end
end
end

def test_first_is_deprecated
assert_deprecated do
db_config = ActiveRecord::Base.configurations.first
assert_equal "arunit", db_config.env_name
assert_equal "primary", db_config.spec_name
end
end

def test_fetch_is_deprecated
assert_deprecated do
db_config = ActiveRecord::Base.configurations.fetch("arunit").first
assert_equal "arunit", db_config.env_name
assert_equal "primary", db_config.spec_name
end
end

def test_values_are_deprecated
config_hashes = ActiveRecord::Base.configurations.configurations.map(&:config)
assert_deprecated do
assert_equal config_hashes, ActiveRecord::Base.configurations.values
end
end

def test_unsupported_method_raises
assert_raises NotImplementedError do
ActiveRecord::Base.configurations.select { |a| a == "foo" }
end
end
end
43 changes: 0 additions & 43 deletions activerecord/test/cases/legacy_configurations_test.rb

This file was deleted.

0 comments on commit 5f71806

Please sign in to comment.