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错误。