通过多个连接进行 Rails Active Record 排序

nex*_*xar 3 join ruby-on-rails include rails-activerecord

我有以下关系。

AdhocBkg
  has_many :invoice_trans
InvoiceTran
  belongs_to :invoice_hdr
  belongs_to :meal
InvoiceHdr
  belongs_to :supplier
  belongs_to :client      
Run Code Online (Sandbox Code Playgroud)

我需要拉出所有具有“已开票”状态的 AdhocBkg,然后通过每个 AdhocBkg 的最后一张发票交易按以下方式对它们进行排序:供应商名称、客户名称、发票编号、发票转运日期和膳食排序顺序。

我目前的代码是:

#AdhocBkg Billed Status ID
abbilledstatusid = AdhocBkgStatus.find_by_abstatdesc('Billed').id
@adhocbkgs = AdhocBkg.find_all_by_abstatusid(abbilledstatusid)
@adhocbkgs.sort! {|x,y| x.invoice_trans.last.invoice_hdr.supplier.suppname + x.invoice_trans.last.invoice_hdr.client.clientname + x.invoice_trans.last.invoice_hdr.invno.to_s + x.invoice_trans.last.invtrndate.strftime('%Y%m%d') + x.invoice_trans.last.meal.mealsortseq.to_s <=> y.invoice_trans.last.invoice_hdr.supplier.suppname + y.invoice_trans.last.invoice_hdr.client.clientname + y.invoice_trans.last.invoice_hdr.invno.to_s + y.invoice_trans.last.invtrndate.strftime('%Y%m%d') + y.invoice_trans.last.meal.mealsortseq.to_s }
Run Code Online (Sandbox Code Playgroud)

上述工作但很慢,主要是因为对数据库的多次读取,我怀疑实际排序。我想知道如何重构代码以使用:include:joins:order子句一起使用,这可能有助于加快速度。但是,我无法弄清楚 Rails Active record 'find' 语句对于上述内容应该是什么。

我在 Ubuntu 11.04 上使用 Rails 3.2.1、Ruby 1.9.3p0 和 MySQL 5.1。

Har*_*eak 5

最后一笔交易是什么?它是具有最大 ID 的那个(查看您的代码,似乎是),还是最新更新的时间戳?

让我们试着弄清楚这一点:

AdHocBkg.joins(:adhoc_bkg_status, :invoice_trans => [ :meal, { :invoice_hdr => [ :supplier, :client ] } ]).
  where("adhoc_bkg_statuses.abstatdesc='Billed' and invoice_trans.id = (select max(id) from invoice_trans as it where it.ad_hoc_bkg_id=ad_hoc_bkgs.id)").
  order("suppliers.suppname desc, clients.clientname desc, invoice_hdrs.invno desc, invoice_trans.invtrndate, meals.mealsortseq desc")
Run Code Online (Sandbox Code Playgroud)

我没有测试过这个,所以不确定它会像你想要的那样工作,但你可以从这里开始。

编辑

如果要访问排序所依据的字段,可以尝试使用includes代替joins