2015-04-04 191 views
0

我有一個簡單的日曆應用程序。Rails LEFT OUTER JOIN子查詢

型號:

class Day < ActiveRecord::Base 
    self.primary_key = "sdate" 
    has_many :items, foreign_key: :sdate 
end 

class Item < ActiveRecord::Base 
    belongs_to :day, :foreign_key => :sdate 
    belongs_to :calendar 
end 

class Calendar < ActiveRecord::Base 
    has_many :items 
end 

要求: 一定時間範圍內獲取的天所有行。 獲取與某些日曆ID相關聯的項目行。

隨着SQL我可以用下面的查詢:

SELECT * FROM days LEFT OUTER JOIN (
    SELECT * FROM items 
    WHERE calendar_id IN (1, 4) 
) AS items 
ON days.sdate = items.sdate 
WHERE days.sdate BETWEEN '2015-03-01' AND '2015-03-31'; 

我曾嘗試在Rails的幾種方法,但我無法找到一個解決方案。

我如何在Rails 4中做到這一點?急切的加載會很好。

+0

那些聽起來像2個不同的要求,他們? – 2015-04-04 10:14:46

回答

0

我只是想弄清楚這一點,我不知道任何方式與純Rails的做到這一點。但是,這會做你想要什麼:

Day.joins("LEFT OUTER JOIN (
    SELECT * FROM items 
    WHERE calendar_id IN (1, 4) 
) AS items 
    ON days.sdate = items.sdate 
    WHERE days.sdate BETWEEN '2015-03-01' AND '2015-03-31'"); 

我不會在我的代碼查詢使用日期,所以我不知道,如果你需要的日期或周圍沒有單引號。但這是語法。我認爲左連接非常方便,我希望Rails有一個實際的LEFT JOIN方法。

+0

謝謝Beartech!我會在今天晚些時候嘗試。 – BugHunter 2015-04-10 08:52:38

+0

對不起,遲到了!我會在接下來的兩天內嘗試。 – BugHunter 2015-04-12 19:47:09

+0

解決方案有效。但不幸的是,在訪問項目 時,它會產生大量額外的數據庫查詢。 – BugHunter 2015-04-13 17:03:16

0

東西沿着這些路線:

Day.joins('LEFT OUTER JOIN items ON days.sdate = items.sdate') 
    .where('items.calendar_id IN (1, 4)') 
    .where('days.sdate' => start_time..end_time) 

http://guides.rubyonrails.org/active_record_querying.html

+0

謝謝你的建議! 不幸的是有一個問題: 如果將有一天,只有一個與calendar_id 3的項目,這一天 將在結果中丟失。 – BugHunter 2015-04-04 15:46:36

+0

另一個問題:沒有物品的日子也不見了。 – BugHunter 2015-04-04 16:09:29

+0

嘗試使用'.to_sql'在控制檯中運行它,並調整它以生成所需的查詢。 – max 2015-04-07 15:17:05