使用Rails ActiveRecord返回带有嵌套结果的查询

时间:2014-10-28 13:48:55

标签: ruby-on-rails ruby sql-server activerecord

我正在尝试为我正在制作的工作流工具获取一系列活动任务,其数据结构如下:

  • 用户
    • has_many项目
      • has_many子项目
        • has_many任务
          • has_many TimeLogs

活动任务被定义为TimeLog没有“完成”时间戳的任何任务。

我正在尝试让主页面显示这个完整的结构,但只显示在某个级别具有活动任务的父结构。查询不应返回任何在其下没有活动任务的用户/项目/子项目。

到目前为止,我已经尝试过:

  • 所有四个表的连接,它产生重复的行
  • WHERE EXISTS语句,仅返回相关用户,但在尝试访问其子级时不维护WHERE子句

有没有办法实现这一点而无需手动剔除Ruby中的数据?

2 个答案:

答案 0 :(得分:1)

由于嵌套级别的问题,可能会非常复杂。据我所知,您想省略没有任何活动任务的用户|项目|子项目。没有简单的SQL可以让你通过以下方式实现:

users.each do |user|
  user.active_projects.each do |project|
    ...
  end
end

相反,我会首先查询任务,即@tasks = Task.includes(:subproject => [:project => :user]).where("status NOT IN ('completed')")。然后你有不完整的任务,现在你需要做的就是重新排序获取的数据,我的意思是:

@tasks = @tasks
.group_by {|t| t.subproject.project.user }
.reduce({}) do |sum, (user, tasks)|
  sum[user] ||= {}
  tasks.each do |task|
    sum[user][task.subproject.project] ||= {}
    sum[user][task.subproject.project][task.subproject] ||= []
    sum[user][task.subproject.project][task.subproject] << task 
  end
  sum
end

我还没有对此进行测试,但这就是想法。

答案 1 :(得分:0)

您可以根据activerecord queries documents

尝试此操作
user.projects.joins(subprojects: { tasks: [{ time_logs: { timestamp: 'completed'} }] })

我无法对其进行测试,但请试一试。