联接表中的ActiveRecord自定义外键只能在一个方向上工作


Table name: bank_accounts        
id              :integer          not null, primary key
number          :string(255)
...
Table name: beneficiary_bank_accounts        
id              :integer          not null, primary key
beneficiary_id  :integer
bene_bank_account_id :integer
Table name: beneficiaries   
id         :integer          not null, primary key
name       :string(255)
...
class BankAccount < ApplicationRecord

has_many :beneficiary_bank_accounts, dependent: :destroy
has_many :beneficiaries, through: :beneficiary_bank_accounts
...
end
class BeneficiaryBankAccount < ApplicationRecord

belongs_to :beneficiary
belongs_to :bene_bank_account, class_name: 'BankAccount', foreign_key: 'bene_bank_account_id'
...
end
class Beneficiary < ApplicationRecord
has_many :beneficiary_bank_accounts, dependent: :destroy
has_many :bene_bank_accounts, through: :beneficiary_bank_accounts, class_name: 'BankAccount'
...
end

在2个表之间存在has_many直通排列,其中如上所示,在BankAccountBeneficiary之间存在以BeneficiaryBankAccount作为联接表的联接表。

名称与另一个定义发生冲突,该定义需要重命名联接表中的一个外键,以帮助ActiveRecord正确推断联接关系。

正如您所看到的,在联接表BeneficiaryBankAccount中,class_name以及bene_bank_account_id列上的外键都已被重写。

我遇到的问题是:

Beneficiary.last.bene_bank_accounts

生成正确的sql

SELECT bank_accounts.* 
FROM bank_accounts 
INNER JOIN beneficiary_bank_accounts ON bank_accounts.id = beneficiary_bank_accounts.bene_bank_account_id WHERE beneficiary_bank_accounts.beneficiary_id = 111 
ORDER BY bank_accounts.title ASC

但是,从相反的方向来看,情况并非如此。

BankAccount.last.beneficiaries

忽略foreign_key覆盖生成不正确的sql

SELECT beneficiaries.* 
FROM beneficiaries 
INNER JOIN beneficiary_bank_accounts ON beneficiaries.id = beneficiary_bank_accounts.beneficiary_id 
WHERE *beneficiary_bank_accounts.bank_account_id* = 135

我已经尝试将foreign_key添加到BankAccount模型中,如:

has_many :beneficiaries, through: :beneficiary_bank_accounts, foreign_key: 'bene_bank_account_id'

这没什么区别。

我看不出有什么方法可以覆盖BankAccount->Beneficiary方向缺少使用原始SQL。

谁能帮我纠正一下吗。

您应该能够通过指定关联的源来实现这一点。

class BankAccount < ApplicationRecord
...
has_many :bene_bank_accounts, through: :beneficiary_bank_accounts, class_name: 'BankAccount', source: :bene_bank_account

这样做的好处是,你不需要知道BeneficiayBankAccount如何与BankAccount建立关联的内部情况,你只需要告诉rails";使用现有的关联,不管它是什么";

看起来解决方案更简单。

有必要将customeforeign_key添加到联接表has_many本身,如所示

has_many :beneficiary_bank_accounts, dependent: :destroy, foreign_key: :bene_bank_account_id
class BankAccount < ApplicationRecord

has_many :beneficiary_bank_accounts, dependent: :destroy, foreign_key: :bene_bank_account_id
has_many :beneficiaries, through: :beneficiary_bank_accounts
...
end

现在两个方向都能正常工作。

谢谢你看。

相关内容

  • 没有找到相关文章

最新更新