РЕДАКТИРОВАТЬ: Нет, они всегда должны использовать rake db: schema: load для существующей БД
.
Я добавляю таблицы истории, заполненные триггерами для аудита в моем проекте через что-то вроде ...
execute <<-SQL
CREATE OR REPLACE FUNCTION process_history_table() RETURNS TRIGGER AS $history_table$
BEGIN
IF (TG_OP = 'DELETE') THEN
INSERT INTO history_table VALUES (DEFAULT, 'D', now(), OLD.*);
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
INSERT INTO history_table VALUES (DEFAULT, 'U', now(), NEW.*);
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
INSERT INTO history_table VALUES (DEFAULT, 'I', now(), NEW.*);
RETURN NEW;
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
$history_table$ LANGUAGE plpgsql;
CREATE TRIGGER history_table
AFTER INSERT OR UPDATE OR DELETE ON table
FOR EACH ROW EXECUTE PROCEDURE process_history_table();
SQL
... и это будет работать для производства и других сред. Проблема в том, когда кто-то бежитbundle exec rake db:drop db:create db:schema:load db:migrate RAILS_ENV=test
или что-то подобное (наиболее важным являетсяdb:schema:load
часть), это будет обходить создание триггера, так как триггеры не сохраняются вdb/schema.rb
файл.
Возможно, правильным решением будет сказать, что при использовании рельсов разработчики никогда не должны запускатьdb:schema:load
и всегда бегатьdb:migrate
вместо этого, чтобы гарантировать, что все миграции могут непрерывно повторяться. Однако мы долгое время не работали таким образом, и я считаю, что это было бы довольно болезненно, поскольку нам может потребоваться обновить несколько десятков или более миграций. Любые мысли о том, как я мог бы постепенно включать триггеры в свое приложение и продолжать создавать / заново создавать среды разработки / тестирования так же, как сегодня, были бы очень полезными.
Спасибо!