I want to override the default rails string type to always strip inputs. I’m aware there are multiplegems which solve this problem, but I felt a custom type is cleaner (while these gems rely on callbacks).
Following documentation I put the following in an initializer:
class StrippedStringType < ActiveRecord::Type::String
def cast(value)
super&.strip
end
end
ActiveRecord::Type.register(:string, StrippedStringType, adapter: :postgresql)
and ActiveRecord::Type.lookup(:string) returns StrippedStringType, however my models still use ActiveModel::Type::String (which I could inspect by calling eg. User.attribute_types["first_name"]).
What’s also a bit weird: as per documentation I expected ActiveRecord::Type.register(:string, ...) to raise an error when called without :override, as we are overriding a native type, but no such thing happened.
Does anyone have any experience with this kind of thing?
I’m not an expert in the Attributes API, but I think it’s not working because you haven’t told your model to use it. It’s likely just picking ActiveRecord::Type::String based on db introspection.
Does it work if you explicitly tell your models to use the new type?
class SomeModel < ApplicationRecord
attribute :some_attribute, StrippedStringType.new
attribute :another_attribute, StrippedStringType.new
end
Yes that would work - however I want this to be picked up automatically, as it affects every :string-column in my app, and I don’t want to define this manually in every model for every :string-column. (That’s what we did in the past, and often forgot)
Monkeypatching ActiveModel::Type::String does what I want, but that seems a bit intrusive.
Overriding the default :string-type is exactly what I want in this case, but it seems I’m misunderstanding the purpose of overriding a type.