2009-04-25 4 views
5

온라인 스토어에서 주문은 "승인 된"상태이고 아직 관련 발송물이없는 경우 출하 준비가 완료되었습니다. 지금 나는 이것을하고있다 :연관된 has_many 객체가없는 모든 객체 찾기

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 

더 좋은 방법이 있습니까?

답변

8

당신은 또한 수 일반 찾기 구문을 사용하여 협회의 쿼리를 사용하여

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

이것은 작동하지 않습니다. has_many 연관이기 때문에 외부 키는 발송 테이블에 저장됩니다. –

+0

우리가 NULL 식별자 –

+0

에 가입하는 이유입니다. 내 잘못 (SQL을 빨아들입니다). 어쨌든 이것은 "상태"를 "상태"(내 특별한 경우)로 바꾸고 "shipments.id"앞에 "and"를 추가해야한다는 것을 제외하면 작동합니다. 이러한 변경 사항을 적용하면이 답변에 표시됩니다. –

1

하나의 옵션은 주문에 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과 같은 프로덕션 DB에서 비슷한 방식으로 개체를 배열 할 수있게되었습니다.

orders.status에 대한 색인이 없다면 강력히 권합니다.

쿼리가 수행하는 작업 : 하위 쿼리는 권한이 부여 된 상태 인 모든 주문의 모든 주문 수를 집계합니다. 선적 횟수가 0 인 쿼리 필터 만 나열하는 외부 쿼리 필터입니다.

당신이 그것을 할 수있는 또 다른 방법은 약간의 직관, 거기에 아마 : 권한 및 선적 테이블에 항목이없는

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

잡아 모든 주문은)

+0

구문은 위조 된 것이어야합니다 : conditions => {: state => "authorized", : shipment_count => 0} ... 즉, 배열이 아닌 해시를 사용하십시오. –

12

에서 레일 3 AREL

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