【发布时间】:2017-12-19 02:58:43
【问题描述】:
所以...
我正在添加由触发器填充的历史表,以便通过类似...的方式在我的项目中进行审计
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 文件中。
也许正确的解决方案是说,在使用 Rails 时,开发人员不应该运行db:schema:load,而是始终运行db:migrate,以确保所有迁移都可以不断地重新运行。但是,我们已经很久没有这样操作了,我相信这样做会很痛苦,因为我们可能需要更新几十个或更多迁移。关于如何逐步将触发器合并到我的应用程序中并让开发人员/测试环境继续以与今天相同的方式构建/重新创建的任何想法将非常有帮助。
谢谢!
【问题讨论】:
标签: ruby-on-rails ruby database postgresql triggers