Rails-有很多,通过查询获取所有嵌套和父对象

时间:2018-11-21 17:49:53

标签: sql ruby-on-rails ruby activerecord

我一直在开发一个调度应用程序,并且遇到了寻找一种有效获取特定记录的方法的问题。

这里是有问题的模型。

class Task < ApplicationRecord
 belongs_to :user, optional: true
 belongs_to :project, optional: true
 belongs_to :project_schedule, optional: true
 belongs_to :user_schedule, optional: true

class User < ApplicationRecord
 include Filterable
 validates :email, presence: true
 validates :email, uniqueness: true
 has_many :tasks 

前端期望的是所有用户的json,其中嵌套了所有任务。加载太多任务变得太麻烦了,我试图指定任务的日期范围,同时仍然吸引所有用户。

所以这似乎比我最初预期的要困难。我可以高效地吸引所有用户,在日期范围内的所有任务,以及在给定日期范围内具有任务(包括任务)的所有用户。但是让所有用户嵌套在给定日期范围内的任务使我无所适从。

我尝试过的

User.filter(params.slice(:project_ids, :email, :id))
 .includes(:tasks).where('((tasks.end_date BETWEEN ? AND ?)
 OR (tasks.start_date BETWEEN ? AND ?))',
 week_start, week_end, week_start, week_end)
 .references(:tasks).order(:name)

我还尝试了合并所有用户以及所有任务在无效范围内的用户。

我觉得关键是原始的SQL,但昨天我无法绕过查询。

任何见解都将有所帮助并受到赞赏。

1 个答案:

答案 0 :(得分:1)

您需要的是左外部联接。但是,如果您有一个WHERE子句,它将过滤掉联接失败的结果,请参见Left Join With Where Clause

您需要将条件指定为JOIN子句的一部分,因此应遵循以下原则:

User.filter(params.slice(:project_ids, :email, :id))
    .joins("LEFT OUTER JOINS tasks ON tasks.user_id = users.id AND 
            tasks.end_date BETWEEN :week_start AND :week_end OR 
            tasks.start_date BETWEEN :week_start AND 
            :week_end", week_start: week_start, week_end: week_end
    .includes(:tasks).order(:name)