在我的 Rails 3.1.3 应用程序中,我有subscriptions
表格;必须跟踪此表上的操作,这对于计费至关重要。由于可以通过多种方式(API、控制台、客户端应用程序)访问数据库,因此简单的 ActiveRecord 回调或观察者不足以确保记录表上的所有事务。因此,我在表上创建了一个数据库触发器,该触发器在subscriptions
任何时候发生变化时都会在“日志”表中插入一条记录。为了做到这一点,我正在使用这样的 Rails 迁移:
def up
execute <<-SQL
CREATE OR REPLACE FUNCTION FUNCTION_Event_Type()
RETURNS TRIGGER
AS
$TRIGGER_Event_Type$
BEGIN
IF (TG_OP = 'DELETE') THEN
INSERT INTO subscription_log (company_id, product_id, old_package_id, new_package_id, trigger_type, updated_at, created_at)
SELECT OLD.company_id, OLD.product_id, OLD.package_id, NULL, 'Delete', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP;
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
INSERT INTO subscription_log (company_id, product_id, old_package_id, new_package_id, trigger_type, updated_at, created_at)
SELECT OLD.company_id, OLD.product_id, OLD.package_id, NEW.package_id, 'Update', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP;
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
INSERT INTO subscription_log (company_id, product_id, old_package_id, new_package_id, trigger_type, updated_at, created_at)
SELECT NEW.company_id, NEW.product_id, NULL, NEW.package_id, 'Insert', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP;
RETURN NEW;
END IF;
RETURN NULL;
END;
$TRIGGER_Event_Type$
LANGUAGE plpgsql;
CREATE TRIGGER TRIGGER_Event_Type
AFTER INSERT OR UPDATE OR DELETE ON subscriptions
FOR EACH ROW EXECUTE PROCEDURE FUNCTION_Event_Type();
SQL
end
触发器工作正常并根据需要记录。我有 rspec 测试检查记录是否插入到“记录”表中,只要在表上完成某些操作subscriptions
。但是,我继续开发该应用程序,并且不得不subscriptions
使用 Rails 迁移向表中添加一列:
def change
add_column :subscriptions, :description, :text
end
运行迁移后,我的测试检查触发器功能如下:
lambda do
FactoryGirl.create(:subscription)
end.should change(SubscriptionLog, :count).by(1)
开始失败。
更新:添加列后,开发数据库仍然有触发器。运行添加列的迁移后,测试数据库丢失触发器......奇怪
问题:
更改表会杀死触发器吗?如果确实如此,那么确保触发器持续存在的方法是什么?