rails/rails — pull request #3941 by azimux (2011-12-11 21:17:16+00:00)
Title: Overrode Hash#nested_under_indifferent_access in HashWithIndifferentAccess

...to return self.

Includes an assertion that fails without the fix.

This fixes a bug where if a subclass of HashWithIndifferentAccess is a value in a hash, and that hash has .with_indifferent_access called upon it, then it becomes a direct instance of HashWithIndifferentAccess instead of the subclass, losing any methods defined in that subclass. This is because Hash#nested_under_indifferent_access creates an instance of HashWithIndifferentAccess directly.

Here's an example of the bug from a rails console:

irb(main):001:0> class HockeyHash < HashWithIndifferentAccess
irb(main):002:1> def hockey_versus opponent
irb(main):003:2> "hockey > #{opponent}"
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):007:0> hash = {:a => HockeyHash.new}
=> {:a=>{}}
irb(main):008:0> hash[:a].hockey_versus("you")
=> "hockey > you"
irb(main):009:0> indifferent_hash = hash.with_indifferent_access
=> {"a"=>{}}
irb(main):010:0> indifferent_hash[:a].hockey_versus("you")
NoMethodError: undefined method `hockey_versus' for {}:ActiveSupport::HashWithIn
differentAccess
from (irb):10
from :0