Favourite Onwuemene
Favourite Onwuemene

Reputation: 4377

ActiveRecord serialize sending nil to custom serializer for present attribute

I have the following custom serializer:

class ReportCardDataSerializer
  def self.dump(hash)
    hash.to_json
  end

  def self.load(json)
    # json.class == NilClass, why????
    hash = (json || {}).with_indifferent_access
  end
end

And the following class with a serialized data attribute with database column set to NOT NULL.

class ReportCardGroup < ActiveRecord::Base
  serialize :data, ReportCardDataSerializer # data is PostgreSQL jsonb column
end

The ReportCardDataSerializer dump method works as expected. But on trying to load ReportCardDataSerializer load method gets sent nil even though the database column is not nil.

Why is this happening?

Upvotes: 4

Views: 1618

Answers (1)

Favourite Onwuemene
Favourite Onwuemene

Reputation: 4377

I figured it out by going through the ActiveRecord serialization class.

ActiveRecord serializer calls type_cast_from_database:

def type_cast_from_database(value)
    if default_value?(value)
      value
    else
      coder.load(super)
    end
end

def default_value?(value)
    value == coder.load(nil) # HERE: Calls Serializer with nil
end

I assumed ReportCardDataSerializer would never have to process nil, but ActiveRecord actually first tries loading nil to test for the default value.

Upvotes: 3

Related Questions