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,

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( do
    def initialize_type_map(m)