1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Fix the config_for to always return a NonSymbolAccessDeprecatedHash:

- If you have hashes inside array, the hashes were getting initialized
  as regular HWIA wereas we want them to be
  NonSymbolAccessDeprecatedHash in order to trigger a deprecation
  warning when keys are accessed with string.

  This patch fixes that by overwriting the `[]=` to to the same
  as what HWIA does (with the difference that we don't call
  `convert_key` to not trigger a deprecation when setting value).

  I also took the liberty to extract `hash.nested_under_indifferent_access`,
  into a separate method to allow subclasses to return whatever
  they want.
  Inheriting HWIA is not common, but I think it's useful for cases
  like this one where we want to preprocess reading and writing values
  in the hash (for deprecation purposes or other reasons).
This commit is contained in:
Edouard CHIN 2019-02-13 13:00:47 +01:00
parent 8d9d46fdae
commit 4f7231da70
3 changed files with 45 additions and 4 deletions

View file

@ -1,3 +1,8 @@
* Fix `Rails.application.config_for` returning a HWIA when Hash were
inside Array.
*Edouard Chin*
* Fix non-symbol access to nested hashes returned from `Rails::Application.config_for`
being broken by allowing non-symbol access with a deprecation notice.

View file

@ -602,10 +602,7 @@ module Rails
end
def []=(key, value)
if value.is_a?(Hash)
value = self.class.new(value)
end
super(key.to_sym, value)
regular_writer(key.to_sym, convert_value(value, for: :assignment))
end
private
@ -623,6 +620,23 @@ module Rails
key
end
def convert_value(value, options = {}) # :doc:
if value.is_a? Hash
if options[:for] == :to_hash
value.to_hash
else
self.class.new(value)
end
elsif value.is_a?(Array)
if options[:for] != :assignment || value.frozen?
value = value.dup
end
value.map! { |e| convert_value(e, options) }
else
value
end
end
end
end
end

View file

@ -1787,6 +1787,28 @@ module ApplicationTests
end
end
test "config_for loads nested custom configuration inside array from yaml with deprecated non-symbol access" do
app_file "config/custom.yml", <<-RUBY
development:
foo:
bar:
- baz: 1
RUBY
add_to_config <<-RUBY
config.my_custom_config = config_for('custom')
RUBY
app "development"
config = Rails.application.config.my_custom_config
assert_instance_of Rails::Application::NonSymbolAccessDeprecatedHash, config[:foo][:bar].first
assert_deprecated do
assert_equal 1, config[:foo][:bar].first["baz"]
end
end
test "config_for makes all hash methods available" do
app_file "config/custom.yml", <<-RUBY
development: