2010-03-24 66 views
3

我已經看過這篇文章幾次,但還沒有真正找到這個具體問題的答案。從ApplicationController中正常自動切換Rails應用程序中的數據庫?

我想運行一個基於檢測到的request.host的rails應用程序(假設我有兩個子域指向相同的rails應用程序和服務器ip地址:myapp1.domain.com和myapp2.domain.com) 。

我想讓myapp1使用默認的「生產」數據庫,而myapp2請求總是使用替代的遠程數據庫。這裏是什麼,我試圖在應用程序控制器,沒有工作做一個例子:

class ApplicationController < ActionController::Base 
    helper :all 
    before_filter :use_alternate_db 

    private 

    def use_alternate_db 

     if request.host == 'myapp1.domain.com' 
     regular_db 
     elsif request.host == 'myapp2.domain.com' 
     alternate_db 
     end 

    end 

    def regular_db 
     ActiveRecord::Base.establish_connection :production 
    end 

    def alternate_db 
     ActiveRecord::Base.establish_connection(
     :adapter => 'mysql', 
     :host => '...', 
     :username => '...', 
     :password => '...', 
     :database => 'alternatedb' 
    ) 

    end 
end 

問題是,當它切換使用此方法的數據庫,所有連接(包括在不同的子域有效會話被打斷.. )。所有在線示例都有人在模型級別控制數據庫連接,但這將涉及在我的應用程序中添加代碼。有沒有一種方法可以按照我上面提出的方式在每個請求的基礎上全局切換數據庫連接,而無需在我的應用程序中注入代碼?

這裏增加的複雜性是我使用Heroku作爲託管提供程序,所以我無法控制apache/rails應用程序服務器級別。

我曾看過像dbcharmer和magicmodels這樣的解決方案,但似乎沒有以我嘗試的方式顯示這樣做的例子。謝謝你的幫助!

回答

3

我從你的問題鍵控關閉此行:

所有連接(包括在不同的子域 有效 會議被打斷......)。

這聽起來像有一些模型,你想連接到生產數據庫,我猜你正在存儲會話在數據庫中。看起來您希望會話保持與生產鏈接,並且您希望切換到其他數據庫。

你可以通過在ActiveRecord和你想改變的模型之間插入一個新類來改變連接。

這個類是這樣的:需要被改變應該從它繼承

class MyAppModel < ActiveRecord::Base 
    self.abstract_class = true 
end 

然後車型:

class User < MyAppModel 
    #stuff 
end 

模型,不應該改變應該保持連接的ActiveRecord。

最後,在您的ApplicationController中,改爲調用MyAppModel上的establish_connection。

你可以根據需要用盡可能多的類來做到這一點。 Model類將向後調整層次結構,直到他們找到具有有效連接的第一個類,並使用它與數據庫進行交互。沒有其他更改是必要的。

+0

謝謝Tilendor,這實際上工作!我最終擴展了所有模型(包括添加一個Session模型來表示我正在使用的數據庫持久會話)。好奇在哪裏我可以學習一點關於如何ActiveRecord建立模型實例的連接.. – Zaqintosh 2010-03-25 06:17:20

+0

RDoc有關於此的一些信息。轉到http://ar.rubyonrails.org/classes/ActiveRecord/Base.html並找到名爲「與多個數據庫在不同模型中連接」的標題。此外,您也可以查看連接池的文檔:http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html – Tilendor 2010-03-25 20:37:57

+0

我發現上面有一個有趣的問題..即使數據庫調用現在已完全分離(基於檢測到的主機名),似乎一個人的較慢連接會影響另一個人。這可能會導致生產中的嚴重問題。我通過訪問執行大量數據庫操作的Web應用程序的一部分進行測試,然後從另一個瀏覽器重新加載「其他數據庫」上的頁面,該頁面通常是即時的......我實際上可以看到它正在等待並等待其他數據庫調用去完成。 切換時是否消除了整個集合池? – Zaqintosh 2010-03-26 00:46:35