brainspec/enumerize

Possible to respond correctly when ActiveRecord is nil?

samstickland opened this issue · 3 comments

Hi,

I've wondering if it's possible to make a change so that when an ActiveRecord object's value is "null", it can still respond correctly? Obviously "null" is usually represented by AR as nil, which results in this sort of behaviour:

class Job < ApplicationRecord
  enumerize :position_type, in: %i[contract permanent]
end
Jobs::Models::Job.new.position_type.contract?
=> NoMethodError: undefined method `contract?' for nil:NilClass

Which means we often have to use the safe navigation operator or symbol/string comparison.

Is this a limitation of the enumerize gem (which is great btw!) or ActiveRecord`s handling of nil/null ? If it's the former I can try and submit a PR for this.

Oh, in a similar vein of types, following on from the above

job = Jobs::Models::Job.new position_type: :contract
job.position_type
=> 'contract'
job.position_type == 'contract'
=> true
job.position_type === 'contract'
=> true
job.position_type == :contract
=> true
job.position_type === :contract
=> false

Seems to me that the last one should also be true? This prevents using symbols in case statements.

And finally, is there any reason for this?

Jobs::Models::Job.new.position_type.class
=> Enumerize::Value
Jobs::Models::Job.new.position_type.is_a? String
=> true

Any thoughts on this?

@samstickland hey!

I've wondering if it's possible to make a change so that when an ActiveRecord object's value is "null", it can still respond correctly? Obviously "null" is usually represented by AR as nil, which results in this sort of behaviour

To avoid this you can use predicate method like Jobs::Models::Job.new&.contract?.

This prevents using symbols in case statements.

To implement this we would need to monkey patch Symbol class and we don't have any plans doing it for now. You can check more info here.

And finally, is there any reason for this?

Yeah, Enumerize::Value is a subclass of String that's why it behaves like this. Probably that wasn't the best decision to subclass String for enumerized value (e.g it caused this bug) but that's what we have now.