Global custom database type registration

Database engines like PostgreSQL support creating custom data types. To use a real example here, I have a custom type for storing monetary amounts that include a currency. I can then use this in any table.

CREATE DOMAIN public.iso3char AS character varying(3)
	CONSTRAINT iso3char_check CHECK (((VALUE IS NULL) OR ((VALUE)::text ~ '^[A-Z]{3}$'::text)));
CREATE TYPE public.currency_amount AS (fractional bigint, currency public.iso3char);

CREATE TABLE accounts (id bigint, balance currency_amount);

Rails supports this. We can create our own type derived from ActiveRecord::Type::Value that implements cast and serialize.

The documented way to use this is with the attribute macro in your model:

class Account
  attribute :amount, CurrencyAmountType.new
end

This works, but it’s not DRY. You end up having to do this for every attribute in every model that uses the custom type. Something pretty generic like my currency_amount could end up with dozens of uses.

I pored over the Rails source and couldn’t find a way to globally register custom types. So, I rolled my own. Question is, is there a reason not to be doing this? I’m wondering if it would make sense to submit a PR to make this standard functionality.

# config/initializers/active_record_custom_types.rb

ActiveSupport.on_load(:active_record) do
  ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.singleton_class.prepend(Module.new do
    def initialize_type_map(m)
      super(m)
      m.register_type("currency_amount", CurrencyAmountType.new)
    end
  end)
end