【问题标题】:Rails Active Record Ordering through multiple joinsRails Active Record 通过多个连接进行排序
【发布时间】:2012-07-09 15:05:30
【问题描述】:

我有以下关系。

AdhocBkg
  has_many :invoice_trans
InvoiceTran
  belongs_to :invoice_hdr
  belongs_to :meal
InvoiceHdr
  belongs_to :supplier
  belongs_to :client      

我需要取出所有处于“已开单”状态的 AdhocBkg,然后按以下方式对它们进行排序: 供应商名称、客户名称、inv no、inv tran 日期和膳食排序顺序,但通过每个 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 }

上述方法有效,但非常慢,主要是因为对数据库的多次读取,我怀疑实际排序。我想知道如何重构代码以使用:include:joins:order 子句,这可能有助于加快速度。但是我无法弄清楚 Rails Active 记录的“查找”语句应该是什么。

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

【问题讨论】:

    标签: ruby-on-rails join include rails-activerecord


    【解决方案1】:

    最后一笔交易是什么?是 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")
    

    我尚未对此进行测试,因此不确定它是否会完全按照您的意愿工作,但您可能可以从这里开始。

    编辑

    如果您想访问您正在排序的字段,您可以尝试使用includes 而不是joins

    【讨论】:

    • 看起来棒极了。我被其他事情拉走了,所以明天早上我会尝试一下,然后告诉你结果。谢谢你。即使它不起作用,我也学会了如何进行嵌套连接,这值得它的重量。顺便说一句,最后一笔交易是具有最大 ID 的交易。 Purvez
    • 太棒了!我不得不做一些小改动,主要是表格的拼写,但唯一可能会引发其他用户的改动是在“where”子句中:invoice_trans.id = (select max(id) from invoice_trans 它应该是:invoice_trans.id = (select max(id) from invoice_trans AS it。我将“AS”放在大写中以突出显示该项目,但当然它应该是小写的。主要是在旧代码下,它需要将近 50 秒才能返回结果。有了这个,它不到 5 秒!!结果!!谢谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多