查找没有关联has_many对象的所有对象

时间:2009-04-25 02:37:40

标签: ruby-on-rails activerecord associations

在我的在线商店中,如果订单处于“已授权”状态并且尚未有任何关联的货件,则该订单已准备好发货。现在我正在这样做:

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

有更好的方法吗?

3 个答案:

答案 0 :(得分:12)

在使用AREL的Rails 3中

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

答案 1 :(得分:8)

您还可以使用常规查找语法查询关联:

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

答案 2 :(得分:3)

一种选择是在装订上放置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。

请注意,如果您在orders.status上没有索引,我强烈建议您这样做!

查询的作用:子查询获取所有处于授权状态的订单的所有订单计数。外部查询过滤列表,只列出出货数等于零的那些。

可能还有另一种方法可以做到这一点,有点违反直觉:

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

抓取所有已授权但在货件表中没有条目的订单;)