2

我想設置一個的has_many:穿過另外兩個型號 用戶和CustomerAccount之間的關係加入模型AccountOwnership (用戶和account_ownerships表是在一個分貝,說DB1和customer_accounts表位於遠程數據庫中,比如說db2)。Rails的:從不同的數據庫中的表之間建立has_many_through協會

下面是相關的代碼,即樹立協會

class User < ActiveRecord::Base 
    has_many :account_ownerships, :dependent => :destroy 
    has_many :companies, :through => :account_ownerships 
end 



class AccountOwnership < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :company, :class_name => "Reporting::CustomerAccount" 
end 


class CustomerAccount < Reporting::Base 
    set_table_name 'customers' 
    establish_connection("db2_#{RAILS_ENV}") 
end 

的config/database.yml的(配置是正確的,雖然這裏沒有顯示)

development: 
    reconnect: false 
    database: db1 
    pool: 5 

db2_development: 
    reconnect: false 
    database: db2 
    host: different.host 
    pool: 5 

在腳本/控制檯

a = AccountOwnership.new(:user_id => 2, :company_id => 10) 

a.user ## Returns the correct user 

a.company ## returns the correct CustomerAccount instance 

a.user.account_ownership ## returns a as anticipated 

a.user.companies ## produces the following error: 
 
#ActiveRecord::StatementInvalid: Mysql::Error: Table 
#'db2.account_ownerships' doesn't exist: SELECT `customers`.* FROM 
#`customers` INNER JOIN `account_ownerships` ON `customers`.id = 
#`account_ownerships`.company_id WHERE ((`account_ownerships`.user_id 
= 4)) 

在這裏的「account_ownerships」和「用戶」表中包含的 一個默認的數據庫(比如DB1)的問題,「客戶」表包含在 不同的數據庫(比如說db2)。到數據庫的連接是 配置正確,但在查找期間,因爲只有一個數據庫 可用的連接對象,Rails嘗試在db2中查找account_ownerships 數據庫,因此失敗。

它看起來像我的設計/邏輯可能是有缺陷的,因爲我看不到的方式 連接到使用同一個數據庫連接兩個不同的數據庫,但我 會很激動,看是否有解決方法,在不改變 設計。 (我不願意更改設計,因爲db2不在我的 控件下)

看起來我可以通過將我的account_ownerships表移動到db2來解決此問題,但這對於我來說並不理想。

是否有任何其他機制/模式來設置此關聯在 Rails中。

在此先感謝。 中號

回答

1

解決方案:

似乎這不能通過任何的Rails關聯魔法來實現,因爲這是任何數據庫訪問機制包括原始SQL的芯限制。

這裏是我做過什麼要解決的問題:

class User < ActiveRecord::Base 
    has_many :account_ownerships, :dependent => :destroy 

    def companies 
    (account_ownerships.collect { |r| Reporting::CustomerAccount.find(r.company_id) }).flatten   
    end  
end 

這提供了一個正確的近似,如下所示:

a = AcccountOwnership.create!(:user_id => 10, :company_id => 10) 
u = User.find(10) 
u.account_ownerships ### will return the correct account_ownership instance 

ALSO

u.companies ### will return a list of all companies enlisted for each account 

我們需要添加兩個實例方法到account_ownership模型,以大致 爲社會交往行爲

class CustomerAccount < ActiveRecord::Base 
    set_table_name "customers"   

    ######################################################## 
    ## This cannot be used because, customers and 
    ## account_ownerships tables are contained in 
    ## different databases, because of this it is 
    ## impossible to query these two tables from a 
    ## single db connection, which is what we are 
    ## attempting to achieve here. 
    ## has_many :account_ownerships, :dependent => :destroy 
    ######################################################## 

    def account_ownerships 
    AccountOwnership.find(:all, :conditions => ["company_id = ?", self.id]) 
    end 

    def users 
    (account_ownerships.collect { |r| User.find(r.user_id) }).flatten 
    end 
end 

現在我們可以做

c = CustomerAccount.find(10) 
c.account_ownerships ## will return the right ownership accounts 

c.users ## will iterate over all the accounts accumulating any users 

注意: 1.由於人們對CustomerAccount模型完成後,如果任何帳戶被刪除沒有刪除級聯,這將不會反映在account_ownership表中,因此這會在用戶方法中產生醜陋的ActiveRecord :: RecordNotFound錯誤。