刚刚为您快速浏览了一个场景,这里是回购:https ://github.com/beneggett/many_db_example
在 repo 中,我只是在本地做了 2 个不同的数据库,但没关系,主体是相同的:
这似乎对我很有效:
告诉账户 account_dim_users 加入表关联,但是通过/habtm 手动映射has_many。
class Account < ActiveRecord::Base
has_many :account_dim_users
def dim_users
account_dim_users.map {|account_dim_user| DimUser.find_by(dwidUser: account_dim_user.dwidUser) }
end
end
这很重要,因为众所周知,标准连接不起作用。但是通过模型映射它可以正常工作。
AccountDimUser 连接表看起来很标准(我明确映射了键)
class AccountDimUser < ActiveRecord::Base
has_many :accounts
has_many :dim_users, primary_key: :dwidUser, foreign_key: :dwidUser
end
手动映射account_dim_users关联,手动映射accounts关联
class DimUser < ActiveRecord::Base
establish_connection "other_db".to_sym
after_initialize :readonly!
self.table_name = 'DimUser'
self.primary_key = 'dwidUser'
def account_dim_users
AccountDimUser.where(dwidUser: self.dwidUser)
end
def accounts
account_dim_users.map {|account_dim_user| Account.find(account_dim_user.account_id) }
end
end
这种方法允许您仍然以标准方式使用 Ruby 对象:
a = Account.first
Account Load (0.6ms) SELECT "accounts".* FROM "accounts" ORDER BY "accounts"."id" ASC LIMIT 1
=> #<Account:0x00000102d263d0> {
:id => 1,
:name => "New account",
:created_at => Mon, 29 Sep 2014 15:07:07 UTC +00:00,
:updated_at => Mon, 29 Sep 2014 15:07:07 UTC +00:00
}
--
a.account_dim_users
=> #<ActiveRecord::Associations::CollectionProxy [#<AccountDimUser id: 1, dwidUser: 1, account_id: 1, created_at: "2014-09-29 15:08:47", updated_at: "2014-09-29 15:08:47">, #<AccountDimUser id: 3, dwidUser: 5, account_id: 1, created_at: "2014-09-29 15:24:17", updated_at: "2014-09-29 15:25:06">]>
--
a.dim_users
AccountDimUser Load (0.3ms) SELECT "account_dim_users".* FROM "account_dim_users" WHERE "account_dim_users"."account_id" = $1 [["account_id", 1]]
DimUser Load (0.9ms) SELECT "DimUser".* FROM "DimUser" WHERE "DimUser"."dwidUser" = 1 LIMIT 1
DimUser Load (0.3ms) SELECT "DimUser".* FROM "DimUser" WHERE "DimUser"."dwidUser" = 5 LIMIT 1
=> [
[0] #<DimUser:0x0000010981af10> {
:id => 1,
:dwidUser => 1,
:created_at => Mon, 29 Sep 2014 15:06:44 UTC +00:00,
:updated_at => Mon, 29 Sep 2014 15:06:44 UTC +00:00
},
[1] #<DimUser:0x00000109838b00> {
:id => 5,
:dwidUser => 5,
:created_at => Mon, 29 Sep 2014 15:23:01 UTC +00:00,
:updated_at => Mon, 29 Sep 2014 15:23:01 UTC +00:00
}
]
--
d = DimUser.first
DimUser Load (0.5ms) SELECT "DimUser".* FROM "DimUser" ORDER BY "DimUser"."dwidUser" ASC LIMIT 1
=> #<DimUser:0x0000010990aad8> {
:id => 1,
:dwidUser => 1,
:created_at => Mon, 29 Sep 2014 15:06:44 UTC +00:00,
:updated_at => Mon, 29 Sep 2014 15:06:44 UTC +00:00
}
--
d.account_dim_users
AccountDimUser Load (0.5ms) SELECT "account_dim_users".* FROM "account_dim_users" WHERE "account_dim_users"."dwidUser" = 1
=> #<ActiveRecord::Relation [#<AccountDimUser id: 1, dwidUser: 1, account_id: 1, created_at: "2014-09-29 15:08:47", updated_at: "2014-09-29 15:08:47">]>
--
d.accounts
AccountDimUser Load (0.5ms) SELECT "account_dim_users".* FROM "account_dim_users" WHERE "account_dim_users"."dwidUser" = 1
Account Load (0.4ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT 1 [["id", 1]]
=> [
[0] #<Account:0x000001099788d0> {
:id => 1,
:name => "New account",
:created_at => Mon, 29 Sep 2014 15:07:07 UTC +00:00,
:updated_at => Mon, 29 Sep 2014 15:07:07 UTC +00:00
}
]
在处理大量记录时,可能会对此进行一些优化,但这是一个很好的基础。
另一种方法可能是对关联表本身进行查找,例如:
def find_dim_user
DimUser.find_by(dwidUser: self.dwidUser)
end
但我非常喜欢我建议的第一种方式,因为它可以让您对关联执行常规的 ruby 方法链接方法。
有其他问题,请告诉我!
编辑:您也可以更改地图功能以使用 Active Record Relations 或类似功能,从而启用更多功能:
class Account < ActiveRecord::Base
has_many :account_dim_users
def dim_users
dim_user_ids = account_dim_users.map {|account_dim_user| account_dim_user.dwidUser }
DimUser.where(dwidUser: dim_user_ids)
end
end