2010-02-07 58 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單呼得好好的,但下面的命名範圍,當我」 m試圖鏈接幾個命名範圍,或者通過關聯範圍來訪問這個named_scope。我認爲,select語句和custom from子句是問題所在。也許有人有一個想法如何重寫這個named_scope以允許鏈接和作用域低谷協會?

編輯:

感謝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」子句,但我已經看到它甚至發生在簡單的關聯上。所以它可能沒有什麼可擔心的。 (但如果別人可以解釋,仍然會很好。) – 2010-02-07 21:11:26

回答

0

您應檢查您的應用程序日誌文件,看看有什麼假設的Rails如果您無法修復它,請向我們展示您嘗試訪問它的示例關聯,然後查詢Rails從日誌文件中生成的查詢

我的本能在這裏Rails認爲它可以訪問表rentable_items,只是rentable_items,但ins tead,在這種情況下,您將其別名爲ri

+0

rails假定它可以訪問表rentable_items。我已經試圖改變命名範圍的select和from部分來滿足這個要求。但是當我這樣做時,mysql抱怨「ambigous fields」。 例如我正在triying訪問account.rentable_items.available_at ... 或 container_item.rentable_items.available_at ... – Sebastian 2010-02-07 20:37:48

+0

我可能已經稍有錯在這裏。它看起來像包裝了整個子查詢,並用'AS t'替代了它。你可以嘗試改變'AS rentable_items'嗎?如果這仍然不起作用,你能編輯問題並粘貼你在日誌文件中看到的SQL嗎? – 2010-02-07 20:48:54