Rails:在不同数据库的表之间设置 has_many_through 关联
我正在尝试设置 has_many :through 两个模型之间的关系 User 和 CustomerAccount 通过另一个联接模型 AccountOwnership (users 和 account_ownerships 表位于一个数据库中,例如 db1,而 customer_accounts 表位于远程数据库中,例如 db2)。
这是设置关联
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”和“users”表包含在 一个默认数据库(例如 db1),“customers”表包含在 不同的数据库(例如 db2)。与数据库的连接是 配置正确,但在查找过程中,因为只有一个数据库 连接对象可用,Rails 尝试查找 account_ownerships db2 中的数据库因此失败。
看来我的设计/逻辑可能有缺陷,因为我看不到办法 使用相同的数据库连接连接到两个不同的数据库,但我 会很高兴看到是否有解决方法,而不改变 设计。 (我不愿意改变设计,因为db2不在我的之下 control)
看来我可以通过将 account_ownerships 表移至 db2 来解决此问题,但这至少对我来说不太理想。
是否有任何替代机制/模式来设置此关联 导轨。
提前致谢。 中号
I am trying to setup a has_many :through relationship between two models
User and CustomerAccount through another join model AccountOwnership
(users and account_ownerships tables are in one db, say db1 and the customer_accounts table is in remote db, say db2).
Here is the relevant code, that sets up the associations
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 (configuration is correct, although not shown here)
development:
reconnect: false
database: db1
pool: 5
db2_development:
reconnect: false
database: db2
host: different.host
pool: 5
In script/console
a = AccountOwnership.new(:user_id => 2, :company_id => 10)
a.user ## Returns the correct user
a.company ## returns the correct CustomerAccount instance
also
a.user.account_ownership ## returns a as anticipated
but
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))
The issue here is that the "account_ownerships" and "users" tables are contained in
one default database (say db1), and the "customers" table is contained in
a different database (say db2). The connections to the databases are
configured properly, but during the lookup since there is only one database
connection object available, Rails tries to find the account_ownerships
database in db2 and hence fails.
It looks like my design/logic might be flawed because I cannot see a way
to connect to two different databases using the same db connection, but I
would be thrilled to see if there is a workaround, without changing the
design. (I am reluctant to change the design because db2 is not under my
control)
It looks like I can workaround this issue by moving my account_ownerships table to db2, but this less than ideal for me atleast.
Are there any alternate mechanisms/schemas to setup this association in
Rails.
Thanks in advance.
M
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
解决方案:
似乎这无法通过任何 Rails 关联魔法来实现,因为这是任何数据库访问机制(包括原始 SQL)的核心限制。
这是我为解决该问题所做的操作:
这提供了正确的近似值,如下所示:
另外
,我们需要向 account_ownership 模型添加两个实例方法,以近似
关联行为
现在我们可以做
并且
注意:
1. 由于 CustomerAccount 模型上没有进行删除级联,因此如果删除任何帐户,这不会反映在 account_ownership 表中,因此这可能会在 users 方法中引起丑陋的 ActiveRecord::RecordNotFound 错误。
Solution:
Seems that this cannot be achieved through any Rails association magic, since this is a core limitation of any database access mechanism including raw SQL.
Here is what I did to workaround the issue:
This provides a correct approximation as shown:
ALSO
And we need to add two instance methods to the account_ownership model, to approximate
the association behavior
Now we can do
AND
CAUTION:
1. Since there is no delete cascading done on the CustomerAccount model, if any accounts are deleted, this will not be reflected in the account_ownership table, hence this can give rise to ugly ActiveRecord::RecordNotFound errors in the users method.