在我的Rails 3.1.3應用程序中,我有subscriptions
表;必須對此表上的操作進行跟蹤,這對計費至關重要。由於數據庫可以以多種方式訪問(API,控制檯,客戶端應用程序),所以簡單的ActiveRecord回調或觀察者不足以確保記錄表上的所有事務。因此,我在subscriptions
表上創建了一個數據庫觸發器,可以隨時在「日誌」表中插入一條記錄進行更改。爲了做到這一點,我正在使用像這樣的Rails遷移:在Rails應用中更改PostgreSQL表格禁用觸發器
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)
開始失敗。
更新:開發數據庫添加一列後仍然有觸發器。測試數據庫運行遷移後失去觸發器,添加一列...奇怪
問題:
是否改變表殺死觸發器?如果確實如此,確保觸發持續的方式是什麼?
你究竟是如何「向列表添加一列」?請顯示代碼。列名也是相關的。它是如何「開始失敗」的?任何錯誤消息?觸發器仍然存在? – 2012-04-26 15:57:02
只有你有這個問題,因爲你有一個糟糕的架構。您的應用程序,控制檯等應該使用api(可能是rails應用程序),並且會有業務規則生存的唯一位置。不在數據庫中。 – 2012-04-26 16:51:21
我不同意@ismaelga。如果多層可以訪問數據庫,則數據庫中的觸發器是最安全的方法。業務規則只在應用程序 - 這本質上是不安全的。 – 2012-04-26 17:11:20