Rails SQL - 将一个表中的qty之和与连接表中的值进行比较

时间:2014-09-08 18:20:18

标签: sql ruby-on-rails

我正在努力处理订单总额中收到的商品数量总和,以确保在有部分订单的情况下关闭订单。

我希望能够创建范围,我将能够返回所有未结订单,然后是所有已结算的订单。

class JobquoteOrder < ActiveRecord::Base
  belongs_to :jobquote
  belongs_to :order
  has_many :po_receipts, dependent: :restrict_with_exception
  has_many :receipts, through: :po_receipts

  scope :receipts, -> {PoReceipt.uniq.pluck(:jobquote_order_id)}

  scope :summed_receipts, ->(jq_id) {PoReceipt
    .where(jobquote_order_id: jq_id)
    .sum(:qty)}

  scope :open_orders, -> {find(receipts)
    .where("jobquote_orders.qty >= #{summed_receipts(:id)}")}
end

在控制台中,JobquoteOrder.open_orders正在返回

JobquoteOrder Load (0.1ms)  SELECT "jobquote_orders".* FROM "jobquote_orders"  WHERE "jobquote_orders"."id" IN (1, 2, 3)
(0.1ms)  SELECT SUM("po_receipts"."qty") AS sum_id FROM "po_receipts"  WHERE "po_receipts"."jobquote_order_id" = 'id'
NoMethodError: undefined method `where' for #<Array:0x007ff9b5958088>

1 个答案:

答案 0 :(得分:0)

我提出这个使它工作,但仍然想知道它是否可以在纯SQL中完成。任何关于重构的建议都会受到欢迎。

class JobquoteOrder < ActiveRecord::Base
  belongs_to :jobquote
  belongs_to :order
  has_many :po_receipts, dependent: :restrict_with_exception
  has_many :receipts, through: :po_receipts
  validates_presence_of :jobquote_id, :order_id, :qty, :total_cost
  validates_uniqueness_of :jobquote_id, scope: [:order_id, :qty, :total_cost], message: 'That order already exists.'

  scope :receipts, -> {PoReceipt.uniq.pluck(:jobquote_order_id)}
  scope :summed_receipt, ->(jq_id) {PoReceipt.where(jobquote_order_id: jq_id)
.sum(:qty)}

  scope :open_orders, -> {find(o_c_orders("open"))}

  scope :closed_orders, -> {find(o_c_orders("closed"))}

  def self.o_c_orders(which)
    ret_arr = []
    case which
    when "open"
      receipts.each do |id|
        ret_arr << id unless is_closed?(id)
      end
      ret_arr << self.includes(:po_receipts).where(:po_receipts => {:id => nil}).pluck(:id)
    when "closed"
      receipts.each do |id|
        ret_arr << id if is_closed?(id)
      end
    end
    return ret_arr
  end

  def self.is_closed?(jq_id)
    jq = self.find(jq_id)
    if jq.qty <= summed_receipt(jq_id)
      true
    else
      false
    end
  end
end