如何解决渴望加载关联模型的最后一条记录
我有一个模型 Invoice
其中 has_many Payments
和一个模型 Payment
belongs_to Invoice
。
Invoice.rb
class Invoice < ApplicationRecord
has_many :payments,inverse_of: :invoice
end
Payment.rb
class Payment < ApplicationRecord
belongs_to :invoice
end
我们每月批量导出Invoice数据,我们需要每个Invoice的最后一次付款。
在我们看来,我们目前对要导出的每个发票执行 Invoice.payments.last
一次,并且我被要求阻止 N+1 查询。
我尝试将以下关联添加到 Invoice
模型:
has_one :last_approved_payment,-> { invoice.payments.approved.last },class_name: "Payment",inverse_of: :invoice
但我收到以下错误:
Invoice.first.last_approved_payment
Invoice Load (0.4ms) SELECT "invoices"."id","invoices"."user_id","invoices"."invoiceable_type","invoices"."invoiceable_id","invoices"."status","invoices"."number","invoices"."period","invoices"."external_id","invoices"."external_status","invoices"."created_at","invoices"."updated_at","invoices"."due_date","invoices"."Metadata","invoices"."rejection_code","invoices"."retry_attempt","invoices"."next_retry_date","invoices"."last_retry_date","invoices"."expire_date","invoices"."external_service","invoices"."external_type","invoices"."external_info","invoices"."account_id","invoices"."temp_due_date","invoices"."next_attempt_date","invoices"."last_attempt_date","invoices"."processing_stage","invoices"."amount_cents","invoices"."amount_currency","invoices"."desist_retrying" FROM "invoices" ORDER BY "invoices"."id" ASC LIMIT $1 [["LIMIT",1]]
Payment Load (0.3ms) SELECT "payments"."id","payments"."operation_id","payments"."status","payments"."status_detail","payments"."payment_type","payments"."external_reference","payments"."payer_email","payments"."date_created","payments"."date_approved","payments"."money_release_date","payments"."comment","payments"."created_at","payments"."updated_at","payments"."user_id","payments"."operation_type","payments"."reason","payments"."reasonable_type","payments"."reasonable_id","payments"."invoice_id","payments"."Metadata","payments"."account_id","payments"."amount_cents","payments"."amount_currency","payments"."payer_id_ciphertext" FROM "payments" LIMIT $1 [["LIMIT",11]]
Payment Load (0.4ms) SELECT "payments"."id",11]]
**NameError: undefined local variable or method `invoice' for #<Payment::ActiveRecord_Relation:0x000055b544ccf138>
from /home/vm/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-6.0.3.6/lib/active_record/relation/delegation.rb:109:in `method_missing'**
解决方法
您无需为模型关系明确添加默认范围,您可以做的只是在检索发票时预加载 payments
表;
Invoice.includes(:payments)
尽管如果您只从两种模型中选择您真正需要的东西,IMO 会更好,但您可以通过使用 select
的子查询来实现:
Invoice.select(
:id,"(SELECT p.id,FROM payments p
WHERE p.invoice_id = invoices.id
ORDER BY created_at DESC
LIMIT 1) AS payment_id"
)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。