2011-09-12 30 views
8

我在嘗試將ActiveRecord gem升級到最新的3.1.0版本,並且看到了很多異常,我認爲這是由於我們如何處理多個數據庫。ActiveRecord 3.1.0多個數據庫

對於我們的每個數據庫,我們指定一個單獨的基類,它繼承自ActiveRecord::Base,並在那裏調用establish_connection。沒有跨數據庫關係。至今爲止,這對我們來說工作得很好。

升級到ActiveRecord 3.1.0我看到,它在失敗時出現ActiveRecord::ConnectionNotEstablished異常,當遍歷關係時(即它將成功從數據庫中拉出單個實體或一組實體,但導航到相關時失敗類)。

回溯的頂線是C:/Ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.1.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:410:in 'retrieve_connection',所以我挖了一點。該方法被定義如下:

def retrieve_connection(klass) #:nodoc: 
    pool = retrieve_connection_pool(klass) 
    (pool && pool.connection) or raise ConnectionNotEstablished 
end 

我的簡單試驗(puts Customer.first.address)調用retrieve_connection 3次。兩次輸入Customer作爲參數klass,一次輸入ActiveRecord::Base作爲參數 - 這是因爲參數establish_connection尚未被調用ActiveRecord::Base

實際問題然後 - 是否有一種新的推薦方式來處理ActiveRecord中的多個數據庫連接?如果是這樣,那是什麼?

如果不是,會導致此問題的原因是什麼?

回答

8

昨天升級到ActiveRecord 3.1.0時遇到了同樣的問題。我不能說在ActiveRecord 3.1中是否有一種新的推薦的處理多個數據庫連接的方式,但我確實找到了一種解除阻止自己的方法。

現在必須在ActiveRecord :: Base上建立連接,以便確定適配器的表名長度/規則。除了在我的數據庫初始化程序中建立的其他連接之外,我現在還有一個ActiveRecord :: Base連接建立到我的一個DB上(哪一個並不重要)。

我想認爲有更好的解決方案可以找到,但我很樂意現在解除封鎖。

+0

謝謝你,還沒有時間嘗試它,但它聽起來像一個很好的解決方案!請回來,讓我們知道,如果你找到更好的方法... –

+0

我們遇到了同樣的問題,並希望找到更好的解決方案。不過,感謝您的幫助。至少我們現在也暢通無阻! – jasonkarns

+0

我自己也會遇到這個問題(activerecord 3.1.3),並按照建議解決了問題。我同意更好的解決方案會更理想。 –

3

我正在使用此解決方案 - 我所看到的是,當每個OtherDb類中調用establish_connection時 - 似乎有很多開銷重新加載表定義,每次重新裝入類def時我都會隨機看到問題。

# The idea here is to specify that a given model should use another 
# database without having to change the entire inheritance hierarchy 

# declare model for table in primary connection 
class Bar < ActiveRecord::Base 
    # assume we have logic here that we don't want to refactor into a module 
    # but we do want to inherit in OtherDb::Bar 
end 

module Foo 

    # base model in Foo namespace - uses another db 
    class BaseConnection < ActiveRecord::Base 
    # OtherDb::Title.database contains a db config hash 
    # This would probably go in the initializers 
    establish_connection OtherDb::Title.database 
    end 

    # module used to override db connection 
    module OtherDb::Base 
    def retrieve_connection 
     # connection_handler.retrieve_connection(self) # normal behavior 
     connection_handler.retrieve_connection(Foo::BaseConnection) # use db from Foo::BaseConnection 
    end 
    end 

    # Foo::Bar is identical to ::Bar but is in another db 
    class Bar < ::Bar 
    extend OtherDb::Base 
    end 
end 
相關問題