2010-02-07 3 views
1

나는이복잡한라는 이름의 범위를 만들 협회 및 기타라는 이름의 범위 [레일]와 함께 좋은 게임 방법

class RentableItem < ActiveRecord::Base 
    named_scope :available_at, lambda{ |starts_at, ends_at| { 
     :select => "t.*", 
     :from => "(SELECT ri.*, COALESCE(c1.start_date, '#{starts_at}') AS EarliestAvailable, 
           COALESCE(c2.end_date, '#{ends_at}') AS LatestAvailable 
       FROM rentable_items ri 
       LEFT OUTER JOIN contracts c1 ON (ri.id = c1.rentable_item_id AND c1.start_date BETWEEN '#{starts_at}' AND '#{ends_at}') 
       LEFT OUTER JOIN contracts c2 ON (ri.id = c2.rentable_item_id AND c2.end_date BETWEEN '#{starts_at}' 
       AND '#{ends_at}' AND c2.start_date >= c1.end_date)) 
       AS t", 
     :joins =>"LEFT OUTER JOIN contracts x ON (t.id = x.rentable_item_id AND x.start_date < t.LatestAvailable 
       AND x.end_date > t.EarliestAvailable)", 
     :conditions => "x.id IS NULL AND DATEDIFF(t.LatestAvailable, t.EarliestAvailable) >= #{(starts_at.to_date..ends_at.to_date).to_a.size - 1}" 
     }} 
end 

이 named_scope의 단일 통화가 마법처럼 작동하지만에 다음과 같은 명명 된 범위 난 '때 여러 개의 명명 된 범위를 함께 연결하려고하거나이 명명 된 범위에 연결 범위를 통해 액세스하려고합니다. 제 생각에는 select 문과 custom 절이 문제입니다. 어쩌면 누군가가이 named_scope를 다시 작성하여 체인 연결 및 스코어링 트로프 연결을 허용하는 방법을 알고 있을지도 모릅니다.

편집 :

감사는 alomst 노력하고 있습니다 Shtééf합니다.

named_scope :available_at, lambda{ |starts_at, ends_at| { 
     :select => "rentable_items.*", 
     :from => "(SELECT ri.*, COALESCE(c1.start_date, '#{starts_at}') AS EarliestAvailable, 
           COALESCE(c2.end_date, '#{ends_at}') AS LatestAvailable 
       FROM rentable_items ri 
       LEFT OUTER JOIN contracts c1 ON (ri.id = c1.rentable_item_id AND c1.start_date BETWEEN '#{starts_at}' AND '#{ends_at}') 
       LEFT OUTER JOIN contracts c2 ON (ri.id = c2.rentable_item_id AND c2.end_date BETWEEN '#{starts_at}' 
AND '#{ends_at}' AND c2.start_date >= c1.end_date)) 
AS rentable_items", 
     :joins =>"LEFT OUTER JOIN contracts x ON (rentable_items.id = x.rentable_item_id AND x.start_date < rentable_items.LatestAvailable 
AND x.end_date > rentable_items.EarliestAvailable)", 
     :conditions => "x.id IS NULL AND DATEDIFF(rentable_items.LatestAvailable, rentable_items.EarliestAvailable) >= #{(starts_at.to_date..ends_at.to_date).to_a.size - 1}" 
     }} 

이 체인에 지금 범위 및 연결을 통해 액세스를 나를 수 있습니다.

시작에서 (생성과 끝 레일 배의 경우 condtion와 어쩌면 단지 화장품, 약간의 문제가있다 :

WHERE (`rentable_items`.container_item_id = 1) AND (((size > 10) AND (x.id IS NULL AND DATEDIFF(rentable_items.LatestAvailable, rentable_items.EarliestAvailable) >= 28)) AND (`rentable_items`.container_item_id = 1)) 
+0

이중 WHERE 절을 만드는 원인이 무엇인지 모르겠지만 간단한 연관에서도이 점을 보았습니다. 그래서 걱정할 것이 없습니다. (하지만 다른 사람이 설명 할 수 있다면 여전히 좋을 것이다.) –

답변

0

당신은 당신의 응용 프로그램에 대한 로그 파일을 검사하고 어떤 가정 레일을 볼 수 생성 된 쿼리가 실패의 원인이되는 결정이다. 당신이 그것을 고칠 우리에게 당신이 그것을 통해 액세스하려는 예를 들어 연결을 보여주고, 쿼리 레일 로그 파일에서 생성 할 수 없습니다. 여기

내 본능 레일즈는 rentable_items 테이블 rentable_items에 액세스 할 수 있다고 가정하지만 이 상황에서 ri으로 별칭을 지정했습니다.

+0

레일즈는 rentable_items 테이블에 액세스 할 수 있다고 가정한다. 이미이 요구 사항을 충족시키기 위해 명명 된 범위의 선택 부분과 부분을 변경하려고했습니다. 그러나 내가 이것을했을 때, mysql은 "모호한 필드"에 대해 불평했다. 예를 들어 은 내가 ... account.rentable_items.available_at에 액세스 할 수 또는 container_item.rentable_items.available_at ... – Sebastian

+0

내가 여기에 약간 잘못되었을 수 있습니다 triying하고있다. 전체 하위 쿼리를 래핑하고 'AS t'로 별칭을 지정한 것처럼 보입니다. 그냥 'AS rentable_items'로 바꾸시겠습니까? 그래도 문제가 해결되지 않으면 질문을 편집하여보고있는 SQL을 로그 파일에 붙여 넣을 수 있습니까? –