Rails LEFT OUTER JOIN子查询

问题描述:

我有一个简单的日历应用程序。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

我只是想弄清楚这一点,我不知道任何方式与纯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

东西沿着这些路线:

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