I had never done it with a trigger yet, but I found this answer that I'm also going to try. But I don't see why it wouldn't work. I changed the answer to try and use the %1$s syntax for interpolating, so you don't have to list the same variable over and over.
CREATE OR REPLACE FUNCTION trigen(tbl text) RETURNS void AS $T1$
BEGIN
EXECUTE format(
'CREATE FUNCTION %1$s_function_name() RETURNS TRIGGER AS $T2$
BEGIN
UPDATE insertions SET n = n + 1 WHERE tablename = %1$s;
RETURN NEW;
END
$T2$ LANGUAGE plpgsql', $1, quote_nullable($1));
EXECUTE format('CREATE TRIGGER %1$s_inCnt BEFORE INSERT ON %s
FOR EACH ROW EXECUTE PROCEDURE %1$s_insertCnt();', $1);
END
$T1$ LANGUAGE plpgsql;
I don't know how you would pass the dynamic name through to the method, but a sample method in Rails could be:
def generate_trigger(table)
ActiveRecord::Base.connection.execute("SELECT trigen(#{table});")
end
And to create the trigger function in your db you can create a migration
def change
reversible do |dir|
dir.up
execute <<-SQL
#trigen function snippet
SQL
end
dir.down do
execute <<-SQL
DROP FUNCTION IF EXISTS trigen() CASCADE
SQL
end
end
end
In order to drop the triggers and trigger functions themselves, you could then make another method in you Rails code,
def drop_trigger(trigger)
ActiveRecord::Base.connection.base.execute("DROP TRIGGER IF EXISTS #{trigger} CASCADE;")
end
def drop_function(function)
ActiveRecord::Base.connection.base.execute("DROP FUNCTION IF EXISTS #{function}() CASCADE;")
end