如何为具有两个外键的模型创建范围?
How to make scope for model, that has two foreign keys?
我有模型 Account
和 Transaction
。
并且模型 Account
在 Transaction
中有两个外键。
transaction.rb:
belongs_to :credit_account, class_name: 'Account',
foreign_key: 'credit_account_id', optional: true
belongs_to :debit_account, class_name: 'Account',
foreign_key: 'debit_account_id', optional: true
此外,事务有列 debit_amount
和 credit_amount
。
account.rb:
has_many :debit_account_transactions,
class_name: 'Transaction',
foreign_key: 'debit_account_id',
dependent: :nullify
has_many :credit_account_transactions,
class_name: 'Transaction',
foreign_key: 'credit_account_id',
dependent: :nullify
我想设定范围,即按交易总和 (debit_amount + credit_amount) 对账户进行排序,使用范围后,我将为每个账户输出 total_amount。
现在,我有下一个范围:
joins(:credit_account_transactions, :debit_account_transactions)
.where('transactions.created_at >= ?', 1.month.ago)
.select(
'accounts.*',
'SUM(transactions.debit_amount_cents) AS total_debit_amount',
'SUM(transactions.credit_amount_cents) AS total_credit_amount',
'SUM(transactions.credit_amount_cents + transactions.debit_amount_cents) AS total_amount'
)
.order('total_amount DESC')
.group('accounts.id')
end
但它不能正常工作。
不算 debit_amount
.
Account.accounts_balance.first.total_credit_amount
=> 1500
Account.accounts_balance.first.total_debit_amount
=> 0
但是如果在 joins(:credit_account_transactions, :debit_account_transactions)
中交换 :credit_account_transactions
和 :debit_account_transactions
它将计算 total_debit_amount
,而 total_credit_amount
- 不会。
您将加入同一个 table 两次。它们会有所不同,并且必须以不同的方式引用。 Rails 尝试变得聪明并重命名第二个连接。
运行 只需 Account.joins(:credit_account_transactions, :debit_account_transactions)
并查看它产生的 sql。它可能是这样的:
SELECT "accounts".* FROM "accounts"
INNER JOIN "transactions"
ON "transactions"."credit_account_id" = "accounts"."id"
INNER JOIN "transactions" "credit_account_transactions_accounts"
ON "credit_account_transactions_accounts"."debit_account_id" = "accounts"."id";
在这里你可以看到在这种情况下,第二个连接被重命名为不同的东西(credit_account_transactions_accounts
),你必须这样引用它。
.select(
'accounts.*',
'SUM(transactions.debit_amount_cents) AS total_debit_amount',
'SUM(credit_account_transactions_accounts.credit_amount_cents) AS total_credit_amount',
我有模型 Account
和 Transaction
。
并且模型 Account
在 Transaction
中有两个外键。
transaction.rb:
belongs_to :credit_account, class_name: 'Account',
foreign_key: 'credit_account_id', optional: true
belongs_to :debit_account, class_name: 'Account',
foreign_key: 'debit_account_id', optional: true
此外,事务有列 debit_amount
和 credit_amount
。
account.rb:
has_many :debit_account_transactions,
class_name: 'Transaction',
foreign_key: 'debit_account_id',
dependent: :nullify
has_many :credit_account_transactions,
class_name: 'Transaction',
foreign_key: 'credit_account_id',
dependent: :nullify
我想设定范围,即按交易总和 (debit_amount + credit_amount) 对账户进行排序,使用范围后,我将为每个账户输出 total_amount。
现在,我有下一个范围:
joins(:credit_account_transactions, :debit_account_transactions)
.where('transactions.created_at >= ?', 1.month.ago)
.select(
'accounts.*',
'SUM(transactions.debit_amount_cents) AS total_debit_amount',
'SUM(transactions.credit_amount_cents) AS total_credit_amount',
'SUM(transactions.credit_amount_cents + transactions.debit_amount_cents) AS total_amount'
)
.order('total_amount DESC')
.group('accounts.id')
end
但它不能正常工作。
不算 debit_amount
.
Account.accounts_balance.first.total_credit_amount
=> 1500
Account.accounts_balance.first.total_debit_amount
=> 0
但是如果在 joins(:credit_account_transactions, :debit_account_transactions)
中交换 :credit_account_transactions
和 :debit_account_transactions
它将计算 total_debit_amount
,而 total_credit_amount
- 不会。
您将加入同一个 table 两次。它们会有所不同,并且必须以不同的方式引用。 Rails 尝试变得聪明并重命名第二个连接。
运行 只需 Account.joins(:credit_account_transactions, :debit_account_transactions)
并查看它产生的 sql。它可能是这样的:
SELECT "accounts".* FROM "accounts"
INNER JOIN "transactions"
ON "transactions"."credit_account_id" = "accounts"."id"
INNER JOIN "transactions" "credit_account_transactions_accounts"
ON "credit_account_transactions_accounts"."debit_account_id" = "accounts"."id";
在这里你可以看到在这种情况下,第二个连接被重命名为不同的东西(credit_account_transactions_accounts
),你必须这样引用它。
.select(
'accounts.*',
'SUM(transactions.debit_amount_cents) AS total_debit_amount',
'SUM(credit_account_transactions_accounts.credit_amount_cents) AS total_credit_amount',