hashie/hashie

Defaults for Trash/Dash objects are ignored when value is set as nil on initialization

bobbytables opened this issue · 2 comments

So I feel like this is supposed to happen but its a bit confusing still.

My goal was to make it if an object is initialized with a hash coming from a Grape API endpoint params, that if the key is set to nil, to convert it to a String. I started looking at defaults as well in this research, but I found something confusing to me.

I have this object:

class WriterParams < Hashie::Trash
  include Hashie::Extensions::IgnoreUndeclared
  include Hashie::Extensions::IndifferentAccess
end

class AllowedParams < WriterParams
  property :description, default: ''
end

When this is ran with this initialization, the description property is set to nil:

ap = AllowedParams.new(description: nil)
#<AllowedParams description=nil>

Ok, no worries, I did explicitly set that, but! The Dash documents caught my eye with this:

p.update_attributes!(occupation: nil)
p.occupation   # => 'Rubyist'

Sure enough, doing an update_attributes! on my AllowedParams class gives the same result:

ap.update_attributes!(description: nil)
{}
(byebug) ap.description
""

So I'm curious why this is the case, is this a bug? I feel like doing an update_attributes! with a nil value should behave the same way as an initialize right?

This looks like a bug to me. The default value means to initialize something to a default "" if not set, then if you set it to anything it should ... set it to whatever value you're setting it to. If you remove the key, it should go the default again.

Always fun to fix these, give it a try :)

Maybe try to at least write a spec for it without class inheritance, etc. The shortest repro.

I looked into this issue this evening and the expected behavior directly conflicts with a test in the suite.

The intended semantics of #update_attributes! are:

  1. Set the value of all attributes specified by the given attribute set, and:
  2. If any of them are nil, set the default, if any

There are some inconsistencies between Dash and Dash/Trash with IgnoreUndeclared mixed in. I am working on a patch that will fix those inconsistencies and add some documentation about #update_attributes!.