Una opción es poner una cuenta_envío en el pedido, donde se actualizará automáticamente con la cantidad de envíos que le anexe. A continuación, sólo
Order.all(:conditions => [:state => "authorized", :shipment_count => 0])
Como alternativa, puede ensuciarse las manos con un poco de 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")
prueba que antes de utilizarlo, tal como SQL no es exactamente mi bolsa, pero creo que está cerca a derecha. Lo hice funcionar para arreglos similares de objetos en mi DB de producción, que es MySQL.
Tenga en cuenta que si no tiene un índice en orders.status, se lo recomendaría encarecidamente.
Qué hace la consulta: la subconsulta capta todos los recuentos de pedidos para todos los pedidos que están en estado autorizado. La consulta externa filtra esa lista solo a las que tienen recuentos de envío igual a cero.
Probablemente hay otra forma en que podría hacerlo, un poco contraintuitiva:
"SELECT DISTINCT orders.* FROM orders
LEFT JOIN shipments ON orders.id = shipments.order_id
WHERE orders.status = 'authorized' AND shipments.id IS NULL"
agarrar todas las órdenes que están autorizados y no tengan una entrada en la tabla de envíos;)
Esto no funcionará. Como es una asociación has_many, la clave externa se almacena en la tabla de envíos. –
Es por eso que nos unimos en el identificador NULL –
Correcto, mi mal (chupo en SQL). De todos modos, esto funciona, excepto que tienes que reemplazar "estado" por "estado" (para mi caso particular) y agregar un "y" antes de "envíos.id". Haz esos cambios, y marcaré esta como respuesta. –