ruby-on-rails 查找不具有关联has_many对象的所有对象

pxyaymoc  于 2022-11-19  发布在  Ruby
关注(0)|答案(4)|浏览(126)

在我的在线商店中,如果订单处于“已授权”状态,并且没有任何关联的发货,则该订单已准备好发货。现在我正在执行以下操作:

class Order < ActiveRecord::Base
    has_many :shipments, :dependent => :destroy

    def self.ready_to_ship
        unshipped_orders = Array.new
        Order.all(:conditions => 'state = "authorized"', :include => :shipments).each do |o|
            unshipped_orders << o if o.shipments.empty?
        end
        unshipped_orders
    end
end

有没有更好的办法?

a6b3iqyw

a6b3iqyw1#

在Rails 3中使用AREL

Order.includes('shipments').where(['orders.state = ?', 'authorized']).where('shipments.id IS NULL')
pxiryf3j

pxiryf3j2#

您也可以使用一般寻找语法来查询相关:

Order.find(:all, :include => "shipments", :conditions => ["orders.state = ? AND shipments.id IS NULL", "authorized"])
e3bfsja2

e3bfsja23#

一个选项是在Order上放置shipment_count,它将自动更新为您附加到它的发货数量。

Order.all(:conditions => [:state => "authorized", :shipment_count => 0])

或者,您也可以使用一些SQL:

Order.find_by_sql("SELECT * FROM
  (SELECT orders.*, count(shipments) AS shipment_count FROM orders 
    LEFT JOIN shipments ON orders.id = shipments.order_id 
    WHERE orders.status = 'authorized' GROUP BY orders.id) 
  AS order WHERE shipment_count = 0")

在使用它之前先测试一下,因为SQL不是我的强项,但我认为它差不多是正确的。我让它在我的生产数据库(MySQL)上工作,对象的排列类似。
请注意,如果你没有一个关于订单的索引。我强烈建议你这样做!
查询的作用:该子查询获取所有处于授权状态的订单的所有订单计数。2外部查询将列表过滤为发货计数等于零的订单。
也许还有另一种方法,有点违反直觉:

"SELECT DISTINCT orders.* FROM orders 
  LEFT JOIN shipments ON orders.id = shipments.order_id
  WHERE orders.status = 'authorized' AND shipments.id IS NULL"

获取所有已授权且在发货表中没有条目的订单;)

hm2xizp9

hm2xizp94#

如果您使用的是Rails 6.1或更高版本,这将非常有效:

Order.where(state: 'authorized').where.missing(:shipments)

相关问题