I have an Entry
class that has a Charge
attribute that I want to instantiate from a string as a Charge
object when read from the DB:
class Entry < ActiveRecord::Base
serialize :charge, Charge
end
class Charge
# Reading from the db as a string
def self.load(str)
str.nil? ? nil : new(str)
end
# Writing to the db as a string
def self.dump(chg)
chg.nil? ? nil : chg.to_s
end
end
This works fine:
ent = Entry.find(1)
ent.charge.class => Charge
However, AR is issuing a deprecation warning:
DEPRECATION WARNING: Passing the coder as positional argument is deprecated and will be removed in Rails 7.2. Please pass the coder as a keyword argument:
serialize :charge, coder: Byr::Charge
But when I do this, AR fails to deserialize the attribute as a Charge but just returns it as a String from the DB.
class Entry < ActiveRecord::Base
serialize :charge, coder: Charge
end
ent = Entry.find(1)
ent.charge.class => String
Am I missing something, or is anyone else seeing this?
To ensure that the serialized attribute charge
is of the Charge
class, you need to specify the :type
parameter in the serializer call. Also, the load
method should return a new empty object when nil
.
The change in the method signature allows you to define separate coder and type classes. This way, your code can load/dump with a certain class and have the attribute be of a different class.
class Entry < ActiveRecord::Base
serialize :charge, coder: Charge, type: Charge
end
class Charge
def self.load(str)
str.nil? ? new(nil) : new(str)
end
end
For more information, see: