hashie/hashie

DeepMerge changes ActiveRecord instance

apotonick opened this issue · 2 comments

Hey folks,

I might be insane, but I'm experiencing something weird when using #deep_merge. In a tiny Rails 7 app, I have a Diagram ActiveRecord model.

diagram = Diagram.find(1)
puts diagram #=> #<Diagram id: 1, name: nil, ...>

class CtxHash < Hash
  include Hashie::Extensions::DeepMerge
end

puts CtxHash[{}].deep_merge(CtxHash[{diagram: diagram}])
#=> {diagram: #<Diagram id: nil, name: nil, ...>}

After the deep merge, the id of the ActiveRecord instance is nil. Any clues? I haven't looked into the source, yet, but remember hashie was doing some automatic subclassing somewhere when cloning.

Hey Nick! #deep_merge performs a #deep_dup on non-Hashes. I believe ActiveRecord models are #duplicable? which means they have #dup called on them. That exhibits the behavior that you're seeing.

Hashie doesn't support rich objects well and never has. It's more of a data munging library that concerns itself with primitives.

Introducing a workaround for ActiveRecord is tricky because we can't depend on Rails constants in the library, but I would be open to a patch that doesn't break backwards compatibility.

Hey Michael! Thanks for responding so quickly! 💚 My first question here would be (regarding hashie as a beautiful munger for primitive datatypes!!!), why are you calling dup on a "flat" object in the first place?