2010-03-25 83 views
5

我有一些初始化函數,用於在PostgreSQL中設置數據庫服務器端的審計日誌記錄(即不是rails)。至少有一個在將數據插入或更新任何審計表之前發佈(設置當前用戶),否則整個查詢將失敗壯觀。如何在Rails中的數據庫連接上執行查詢?

在代碼中運行任何保存操作之前,我可以很容易地調用這些代碼,但DRY讓我覺得我應該讓代碼在儘可能少的地方重複使用,特別是因爲這與數據庫不可知論的理想差異很大。目前我試圖在初始化器中重寫ActiveRecord :: Base.establish_connection來設置它,以便在我自動連接時立即運行查詢,但它不像我期望的那樣運行。這裏是初始化代碼:

 
class ActiveRecord::Base 
    # extend the class methods, not the instance methods 
    class << self 
    alias :old_establish_connection :establish_connection # hide the default 

    def establish_connection(*args) 
     ret = old_establish_connection(*args) # call the default 

     # set up necessary session variables for audit logging 
     # call these after calling default, to make sure conn is established 1st 
     db = self.class.connection 
     db.execute("SELECT SV.set('current_user', '[email protected]')") 
     db.execute("SELECT SV.set('audit_notes', NULL)") # end "empty variable" err 

     ret # return the default's original value 
    end 
    end 
end 

puts "Loaded custom establish_connection into ActiveRecord::Base" 
 
sycobuny:~/rails$ ruby script/server 
=> Booting WEBrick 
=> Rails 2.3.5 application starting on http://0.0.0.0:3000 
Loaded custom establish_connection into ActiveRecord::Base 

這不會給我任何錯誤,不幸的是我無法檢查什麼方法看起來像內部(我用的ActiveRecord :: Base.method (:establish_connection),但顯然每次調用時都會創建一個新的Method對象,這看起來毫無價值,因爲我無法檢查object_id是否有任何有價值的信息,而且我也無法撤消編譯)。

但是,代碼似乎永遠不會被調用,因爲任何嘗試在數據庫對象上運行保存或更新都失敗,正如我之前所預測的那樣。如果這不是在連接數據庫時立即執行代碼的正確方法,那麼是什麼?

回答

3

Rails使用連接池,所以最好的辦法是使用ActiveRecord的:: ConnectionAdapters的alias_method_chain ::連接池#new_connection

module ActiveRecord 
    Module ConnectionAdapters 
    class ConnectionPool 
     alias_method_chain :new_connection, :my_stuff 
     private 
     def new_connection_with_my_stuff 
     c = new_connection_without_my_stuff 
     # Do your stuff with 
     # c.exec(<your sql command>) 
     c 
     end 
    end 
    end 
end 
+0

我相信alias_method_chain需要在聲明該方法後運行。 – Kevin 2010-03-29 16:35:29

+0

在聲明該方法後,需要調用alias_method_chain,否則將無法找到該方法。另外,運行c的方法是執行的,而不是exec(我相信它給我的錯誤是exec是私有的)。但否則,這解決了我遇到的問題。謝謝! – sycobuny 2010-03-31 16:02:32

+0

以及如何在此上下文中獲取*當前用戶* – mlt 2016-10-06 21:22:32

0

你知道你的初始化器在數據庫連接建立之前被調用嗎?

如果沒有可能出現錯誤的權威信息,我會利用ActiveRecord的源位於我的硬盤上。

挖掘基類並做一些調試,以查看何時調用ActiveRecord establish_connection相對於初始化程序的調用時間。無論是或者只是打開額外的詳細調試。

0

在寫代碼掛鉤的條款軌數據庫調用和初始化,您可能想要使用db-charmer中的代碼作爲模板。它演示了一些與ActiveRecord交互的有趣方法,其中一個可能會按照你的意願做。