Remove deprecated non-symbol access to nested config_for hashes
This commit is contained in:
parent
cf27cfa18b
commit
e5e9c558a3
@ -75,6 +75,30 @@ To allow you to upgrade to new defaults one by one, the update task has created
|
||||
Upgrading from Rails 6.0 to Rails 6.1
|
||||
-------------------------------------
|
||||
|
||||
### `Rails.application.config_for` return value no longer supports access with String keys.
|
||||
|
||||
Given a configuration file like this:
|
||||
|
||||
```yaml
|
||||
# config/example.yml
|
||||
development:
|
||||
options:
|
||||
key: value
|
||||
```
|
||||
|
||||
```ruby
|
||||
Rails.application.config_for(:example).options
|
||||
```
|
||||
|
||||
This used to return a hash on which you could access values with String keys. That was deprecated in 6.0, and now doesn't work anymore.
|
||||
|
||||
You can call `with_indifferent_access` on the return value of `config_for` if you still want to access values with String keys, e.g.:
|
||||
|
||||
```ruby
|
||||
Rails.application.config_for(:example).with_indifferent_access.dig('options', 'key')
|
||||
```
|
||||
|
||||
|
||||
### Response's Content-Type when using `respond_to#any`
|
||||
|
||||
The Content-Type header returned in the response can differ from what Rails 6.0 returned,
|
||||
|
@ -1,3 +1,20 @@
|
||||
* Remove access to values in nested hashes returned by `Rails.application.config_for` via String keys.
|
||||
|
||||
```yaml
|
||||
# config/example.yml
|
||||
development:
|
||||
options:
|
||||
key: value
|
||||
```
|
||||
|
||||
```ruby
|
||||
Rails.application.config_for(:example).options
|
||||
```
|
||||
|
||||
This used to return a Hash on which you could access values with String keys. This was deprecated in 6.0, and now doesn't work anymore.
|
||||
|
||||
*Étienne Barrié*
|
||||
|
||||
* Configuration files for environments (`config/environments/*.rb`) are
|
||||
now able to modify `autoload_paths`, `autoload_once_paths`, and
|
||||
`eager_load_paths`.
|
||||
|
@ -228,11 +228,11 @@ def config_for(name, env: Rails.env)
|
||||
|
||||
if yaml.exist?
|
||||
require "erb"
|
||||
config = YAML.load(ERB.new(yaml.read).result) || {}
|
||||
config = (config["shared"] || {}).merge(config[env] || {})
|
||||
config = YAML.load(ERB.new(yaml.read).result, symbolize_names: true) || {}
|
||||
config = (config[:shared] || {}).merge(config[env.to_sym] || {})
|
||||
|
||||
ActiveSupport::OrderedOptions.new.tap do |options|
|
||||
options.update(NonSymbolAccessDeprecatedHash.new(config))
|
||||
options.update(config)
|
||||
end
|
||||
else
|
||||
raise "Could not load configuration. No such file - #{yaml}"
|
||||
@ -604,51 +604,5 @@ def build_request(env)
|
||||
def build_middleware
|
||||
config.app_middleware + super
|
||||
end
|
||||
|
||||
class NonSymbolAccessDeprecatedHash < HashWithIndifferentAccess # :nodoc:
|
||||
def initialize(value = nil)
|
||||
if value.is_a?(Hash)
|
||||
value.each_pair { |k, v| self[k] = v }
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def []=(key, value)
|
||||
regular_writer(key.to_sym, convert_value(value, for: :assignment))
|
||||
end
|
||||
|
||||
private
|
||||
def convert_key(key)
|
||||
unless key.kind_of?(Symbol)
|
||||
ActiveSupport::Deprecation.warn(<<~MESSAGE.squish)
|
||||
Accessing hashes returned from config_for by non-symbol keys
|
||||
is deprecated and will be removed in Rails 6.1.
|
||||
Use symbols for access instead.
|
||||
MESSAGE
|
||||
|
||||
key = key.to_sym
|
||||
end
|
||||
|
||||
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
|
||||
|
@ -1934,47 +1934,6 @@ class D < C
|
||||
assert_equal 1, Rails.application.config.my_custom_config[:foo][:bar][:baz]
|
||||
end
|
||||
|
||||
test "config_for loads nested custom configuration 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"
|
||||
|
||||
assert_deprecated do
|
||||
assert_equal 1, Rails.application.config.my_custom_config["foo"]["bar"]["baz"]
|
||||
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:
|
||||
@ -1999,87 +1958,6 @@ class D < C
|
||||
assert_equal({ baz: 1 }, actual[:bar])
|
||||
end
|
||||
|
||||
test "config_for generates deprecation notice when nested hash methods are called with non-symbols" do
|
||||
app_file "config/custom.yml", <<-RUBY
|
||||
development:
|
||||
foo:
|
||||
bar: 1
|
||||
baz: 2
|
||||
qux:
|
||||
boo: 3
|
||||
RUBY
|
||||
|
||||
app "development"
|
||||
|
||||
actual = Rails.application.config_for("custom")[:foo]
|
||||
|
||||
# slice
|
||||
assert_deprecated do
|
||||
assert_equal({ bar: 1, baz: 2 }, actual.slice("bar", "baz"))
|
||||
end
|
||||
|
||||
# except
|
||||
assert_deprecated do
|
||||
assert_equal({ qux: { boo: 3 } }, actual.except("bar", "baz"))
|
||||
end
|
||||
|
||||
# dig
|
||||
assert_deprecated do
|
||||
assert_equal(3, actual.dig("qux", "boo"))
|
||||
end
|
||||
|
||||
# fetch - hit
|
||||
assert_deprecated do
|
||||
assert_equal(1, actual.fetch("bar", 0))
|
||||
end
|
||||
|
||||
# fetch - miss
|
||||
assert_deprecated do
|
||||
assert_equal(0, actual.fetch("does-not-exist", 0))
|
||||
end
|
||||
|
||||
# fetch_values
|
||||
assert_deprecated do
|
||||
assert_equal([1, 2], actual.fetch_values("bar", "baz"))
|
||||
end
|
||||
|
||||
# key? - hit
|
||||
assert_deprecated do
|
||||
assert(actual.key?("bar"))
|
||||
end
|
||||
|
||||
# key? - miss
|
||||
assert_deprecated do
|
||||
assert_not(actual.key?("does-not-exist"))
|
||||
end
|
||||
|
||||
# slice!
|
||||
actual = Rails.application.config_for("custom")[:foo]
|
||||
|
||||
assert_deprecated do
|
||||
slice = actual.slice!("bar", "baz")
|
||||
assert_equal({ bar: 1, baz: 2 }, actual)
|
||||
assert_equal({ qux: { boo: 3 } }, slice)
|
||||
end
|
||||
|
||||
# extract!
|
||||
actual = Rails.application.config_for("custom")[:foo]
|
||||
|
||||
assert_deprecated do
|
||||
extracted = actual.extract!("bar", "baz")
|
||||
assert_equal({ bar: 1, baz: 2 }, extracted)
|
||||
assert_equal({ qux: { boo: 3 } }, actual)
|
||||
end
|
||||
|
||||
# except!
|
||||
actual = Rails.application.config_for("custom")[:foo]
|
||||
|
||||
assert_deprecated do
|
||||
actual.except!("bar", "baz")
|
||||
assert_equal({ qux: { boo: 3 } }, actual)
|
||||
end
|
||||
end
|
||||
|
||||
test "config_for uses the Pathname object if it is provided" do
|
||||
app_file "config/custom.yml", <<-RUBY
|
||||
development:
|
||||
|
Loading…
Reference in New Issue
Block a user