【问题标题】:Rails, PostgreSQL, and History TriggersRails、PostgreSQL 和历史触发器
【发布时间】: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


    【解决方案1】:

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

    切换很简单:

    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 中进行跟踪,并且重新创建数据库不会丢失它们。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        https://github.com/jenseng/hair_trigger不是你需要的吗?

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

        注意:我一直想使用它,但由于各种原因最终没有机会使用它,因此我无法保证宝石的质量。

        编辑:不,他们应该始终对现有数据库使用 rake db:schema:load

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-08-01
          • 2012-10-28
          • 2010-10-19
          • 1970-01-01
          • 1970-01-01
          • 2016-07-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多