Если ваша единственная цель состоит в том, чтобы получить количество заданий для каждой рабочей области, я думаю, что вам нужен другой запрос.
@workspaces_with_task_counts =
Workspace
.joins(:projects)
.joins(:tasks)
.select('workspaces.name, count(tasks.id) as task_count')
.group(:workspace_id)
Тогда вы можете получить доступ к счетчику следующим образом:
@workspaces_with_task_counts.each do |workspace|
puts "#{workspace.name}: #{workspace.task_count}"
end
РЕДАКТИРОВАТЬ 1
Я думаю, что это то, что вы хотите:
Workspace
.joins(projects: { tasks: :urgencies })
.where(urgencies: {urgency_value: 7})
.group(:name)
.count
, в результате чего получается хеш, содержащий все рабочие пространства, по крайней мере с одной задачей, где urgency_valueравно 7 по имени с количеством задач в этом рабочем пространстве:
{"workspace1"=>4, "workspace2"=>1}
РЕДАКТИРОВАТЬ 2
SQL не способен возвращать как подробную, так и сводную информацию водин запрос.Но мы можем получить все данные, а затем суммировать их в памяти с помощью метода group_by
Руби:
Task
.joins(project: :workspace)
.includes(project: :workspace)
.group_by { |task| task.project.workspace.name }
Это создает следующую структуру данных:
{
"workspace1": [task, task, task],
"workspace2": [task, task],
"workspace3": [task, task, task, task]
}
Но это делаеттак по цене.Группировка в памяти - дорогой процесс.Выполнение этого запроса 10000 раз заняло ~ 15 секунд.
Оказалось, что выполнение двух запросов SQL на самом деле на два порядка быстрее за ~ 0,2 секунды.Вот запросы:
tasks = Task.joins(project: :workspace).includes(project: :workspace)
counts = tasks.group('workspaces.name').count
Первый запрос получает все задачи и предварительно загружает связанные с ними данные проекта и рабочей области.Второй запрос использует предложение ActiveRecord group
для создания оператора SQL для суммирования данных.Он возвращает такую структуру данных:
{ "workspace1": 3, "workspace2": 2, "workspace3": 4 }
Базы данных очень эффективны при манипулировании множествами.Почти всегда значительно быстрее выполнять эту работу в базе данных, чем в Ruby.