Rails,PostgreSQL和历史触发器

问题描述 投票:1回答:3

所以...

我正在通过类似的东西添加由触发器填充的历史表,以便在我的项目中进行审计。

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
3个回答
5
投票

如果您需要或想要ActiveRecord不理解的特定于数据库的功能,那么您应该切换到db/structure.sql以跟踪您的架构。 db/structure.sql几乎是使用数据库的本机工具制作的模式的原始转储,因此它将包含触发器,CHECK约束,函数结果索引以及其他所有内容。

切换很简单:

  1. 更新你的config/application.rb以包含config.active_record.schema_format = :sql
  2. 做一个rake db:structure:dump得到一个初始db/structure.sql
  3. 从目录树和版本控制中删除db/schema.rb
  4. db/structure.sql添加到版本控制。
  5. 调整你的佣金习惯: 使用db:structure:dump而不是db:schema:dump 使用db:structure:load而不是db:schema:load

其他一切都应该像往常一样工作(当然,假设你是理智的,并使用PostgreSQL进行开发,测试和生产)。

完成此更改后,将在db/structure.sql中跟踪您的触发器,并重新创建数据库不会丢失它们。


0
投票

您可以使用跟踪更改为模型的gem 'paper_trail'进行审核或版本控制。 Here is the Link


0
投票

是不是https://github.com/jenseng/hair_trigger你需要什么?

它允许您在项目中注册触发器,然后重新创建,使用命令更新它们。

注意:我一直想使用它,但由于各种原因最终没有机会完成它,所以我不能保证宝石的质量。

编辑:不,他们应该总是使用rake db:schema:加载现有的数据库

© www.soinside.com 2019 - 2024. All rights reserved.