Skip to content

Instantly share code, notes, and snippets.

@inopinatus
Created April 23, 2021 02:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save inopinatus/f7313b9efe9909f5ddc1e514fe639ebb to your computer and use it in GitHub Desktop.
Save inopinatus/f7313b9efe9909f5ddc1e514fe639ebb to your computer and use it in GitHub Desktop.
dangerous polymorphic fun with primary key casts (nsfw)
class CastIdsToText < ActiveRecord::Migration[6.0]
def up
add_cast :text, :uuid, function: :inout, context: :implicit
add_cast :text, :bigint, function: :inout, context: :implicit
end
def down
remove_cast :text, :uuid
remove_cast :text, :bigint
end
private
def add_cast(source_type, target_type, function: :binary, context: nil)
cast_argument = "#{source_type} AS #{target_type}"
method_argument = case function
when :inout
"WITH INOUT"
when :binary, nil
"WITHOUT FUNCTION"
else
"WITH FUNCTION #{function.to_s}"
end
context_argument = case context
when :implicit
"AS IMPLICIT"
when :assignment
"AS ASSIGNMENT"
else
context.to_s
end
connection.execute <<~DDL
DO $$ BEGIN
CREATE CAST (#{cast_argument}) #{method_argument} #{context_argument};
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
DDL
end
def remove_cast(source_type, target_type)
cast_argument = "#{source_type} AS #{target_type}"
connection.execute <<~DDL
DROP CAST IF EXISTS (#{cast_argument});
DDL
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment