2014-10-28 2 views
0

Я пытаюсь захватить список активных задач для инструмента рабочего процесса я делаю, с данными структурированы следующим образом:Возвращает запрос с вложенными результатами с Rails ActiveRecord

  • Пользователя
    • has_many проекты
      • HAS_MANY подпроектах
        • HAS_MANY задачи
          • HAS_MANY T imeLogs

Активные задачи определяются как любые задачи с TimeLog, что не имеет 'заполненный' временную метку.

Я стараюсь, чтобы главная страница отображала эту полную структуру, но отображала только родительские структуры, у которых есть активная задача на некотором уровне. Любые пользователи/проекты/подпроекты, которые не имеют активной задачи под ними, не должны возвращаться запросом.

До сих пор я пытался:

  • Объединение всех четырех таблиц, которые производит повторяющиеся строки
  • ГДЕ СУЩЕСТВУЕТ заявление, которое возвращает только соответствующие пользователи, но не поддерживать WHERE когда я пытаюсь получить доступ к его детям

Есть ли способ достичь этого без ручного отбраковки данных в Ruby?

+0

Вы можете добавить '.uniq' в конец вашего запроса на соединение. Затем ActiveRecord запросит без дубликатов. –

+0

Это работает для пользователей верхнего уровня, но когда я захватываю дочерние проекты пользователя, он просто захватывает все проекты. Выполнение предложения 'where' через детей кажется беспорядочным, поэтому я ищу способ просто захватить все это сразу, возможно, преобразовать запрос ActiveRecord в вложенный хэш? –

ответ

1

Из-за вложенного уровня проблемы это может быть довольно сложно. Насколько я понимаю, вы хотите опустить подпроекты пользователей | projects |, которые не имеют активных задач. Там нет простого 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 

Я не проверял это, но это идея.

+0

Bleh, поэтому лучший способ сделать это - построить дерево вручную. Я беспокоился, что это будет так. Спасибо за образцы кода. –

0

Вы можете попробовать это на основе activerecord queries documents:

user.projects.joins(subprojects: { tasks: [{ time_logs: { timestamp: 'completed'} }] }) 

Я не могу проверить это, но дать ему шанс.

+0

К сожалению, это была моя первая идея, но объединение возвращает повторяющиеся строки, если у Пользователя имеется более одной активной задачи, и, как я упоминал в комментариях, '.uniq' не применяет предложение' where' к дочерним отношениям. –

Смежные вопросы