Skip to content

Commit e857454

Browse files
committed
Fix ActiveSupport::HashWithIndifferentAccess#stringify_keys to stringify all keys not just symbols.
Fix: rails#53008 ```ruby { 1 => 2 }.with_indifferent_access.stringify_keys[1] # => 2 ``` After this change: ```ruby { 1 => 2 }.with_indifferent_access.stringify_keys["1"] # => 2 ```
1 parent 26a4a5d commit e857454

File tree

3 files changed

+30
-4
lines changed

3 files changed

+30
-4
lines changed

activesupport/CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
* Fix `ActiveSupport::HashWithIndifferentAccess#stringify_keys` to stringify all keys not just symbols.
2+
3+
Previously:
4+
5+
```ruby
6+
{ 1 => 2 }.with_indifferent_access.stringify_keys[1] # => 2
7+
```
8+
9+
After this change:
10+
11+
```ruby
12+
{ 1 => 2 }.with_indifferent_access.stringify_keys["1"] # => 2
13+
```
14+
15+
This change can be seen as a bug fix, but since it behaved like this for a very long time, we're deciding
16+
to not backport the fix and to make the change in a major release.
17+
18+
*Jean Boussier*
19+
120
## Rails 8.0.0.beta1 (September 26, 2024) ##
221
322
* Include options when instrumenting `ActiveSupport::Cache::Store#delete` and `ActiveSupport::Cache::Store#delete_multi`.

activesupport/lib/active_support/hash_with_indifferent_access.rb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -313,10 +313,6 @@ def except(*keys)
313313
end
314314
alias_method :without, :except
315315

316-
def stringify_keys!; self end
317-
def deep_stringify_keys!; self end
318-
def stringify_keys; dup end
319-
def deep_stringify_keys; dup end
320316
undef :symbolize_keys!
321317
undef :deep_symbolize_keys!
322318
def symbolize_keys; to_hash.symbolize_keys! end

activesupport/test/hash_with_indifferent_access_test.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,17 @@ def test_symbolize_keys_preserves_integer_keys_for_hash_with_indifferent_access
9898
assert_raise(NoMethodError) { @integers.with_indifferent_access.dup.symbolize_keys! }
9999
end
100100

101+
def test_stringify_keys_stringifies_integer_keys_for_hash_with_indifferent_access
102+
assert_equal({ "0" => 1, "1" => 2 }, @integers.with_indifferent_access.stringify_keys)
103+
assert_equal({ "ints" => { "0" => 1, "1" => 2 } }, { ints: @integers }.with_indifferent_access.deep_stringify_keys)
104+
end
105+
106+
def test_stringify_keys_stringifies_non_string_keys_for_hash_with_indifferent_access
107+
object = Object.new
108+
hash = { object => 1 }
109+
assert_equal({ object.to_s => 1 }, hash.with_indifferent_access.stringify_keys)
110+
end
111+
101112
def test_deep_symbolize_keys_preserves_integer_keys_for_hash_with_indifferent_access
102113
assert_equal @nested_integers, @nested_integers.with_indifferent_access.deep_symbolize_keys
103114
assert_raise(NoMethodError) { @nested_integers.with_indifferent_access.deep_dup.deep_symbolize_keys! }

0 commit comments

Comments
 (0)