I am following this pattern to ensure all my attributes are normalized before they are saved:
class MyModel < ApplicationRecord
before_validation :normalize_attributes
def normalize_attributes
self.name&.strip!
self.email&.strip!
end
end
I have also some others more complicated:
def normalize_attributes
# Transform to array if it is a string with things
# separated by comas
if self.favorite_things.is_a? String
self.favorite_things = self.favorite_things.split(",").map(&:strip)
end
end
It works, but the problem is that when I add this attribute to the serialized
ones it fails:
serialize :favorite_things, Array
Like in here:
my_model.update(favorite_things: "ONE, TWO, THREE")
The error:
Error:
ActiveRecord::SerializationTypeMismatch: can't serialize `favorite_things`: was supposed to be a Array, but was a String. -- "ONE, TWO, THREE"
It looks like the serialize
command is executed before the before_validation
.
How can I sanitize attributes before they are serialized?
In order to ensure all your attributes are normalized before saving - overwrite setters:
class MyModel < ApplicationRecord
# @param value [String]
# @return [String]
def name=(value)
super(value.strip)
end
# @param value [String]
# @return [String]
def email=(value)
super(value.strip)
end
# @param value [String, Array]
# @return [Array]
def favorite_things=(value)
return super(value) unless value.is_a? String
super(favorite_things.split(",").map(&:strip))
end
end