Rails 5 - 'parent'名称和'child'计数的查询关联



>Models

用户有客户

,客户有有任务的项目。

我正在尝试构建一个带有 [名称、计数] 的数组以发送到 Google 图表 - 除了一个之外,我已经解决了所有这些问题:

def task_by_project(user)
    task_arr = user.projects.joins(:tasks).where("tasks.completed = ?", "0").uniq.collect { |d| [d.name, d.tasks.count] }.to_a
    task_arr.unshift(['Projects', 'Uncompleted Tasks'])
    return task_arr
end

此查询返回 11 个条目。这实际上是该用户的所有条目。它完全绕过了where。有7个未完成的4个已完成。

在视图中,我用循环渲染它略有不同:

    <% current_user.projects.uniq.each do |project| %>
      <%= link_to project.name + " || " + project.tasks.where(completed: 0).count.to_s + " tasks remaining currently", project, :class => "collection-item" %>
    <% end %>  
  </div>

我相当有信心这与我对如何查询如此深刻的关联的误解有关。

最终结果是我需要项目的名称,以及它有多少任务。

我通过查询将Task连接回Project.ID Project来做到这一点 - 但我不确定如何处理整个集合。

("取消移位"的目的是因为从其他方面来看,我最终得到的结果格式是[[['Projects', 'Tasks'], [['First Record, 2] ... ]]而不是 GCharts 格式。更平坦的杀了它 - 太多 - )

也许是这样的?

projects = user.projects
  .select("projects.name, COUNT(uncompleted_tasks.id) AS uncompleted_tasks_count")
  .joins("LEFT OUTER JOIN tasks AS uncompleted_tasks ON uncompleted_tasks.project_id = projects.id AND uncompleted_tasks.completed = 0")
  .group("projects.id")
  .map { |project| [project.name, project.uncompleted_tasks_count] }

改用 .pluck 获取列值

user.projects.left_joins(:tasks).where("tasks.completed = 0")
    .distinct
    .pluck('users.id, users.name, tasks.count')
    .map { |a| a.pop(2) }

.pluck效率要高得多,因为它只是查询传递给 ppick 的列并返回数组数组,而不是将一堆模型加载到内存中。

 # => [[1, 'Frank', 0], [2, 'Muhammad', 5], [3, 'Jane', 3]]

但是,除非您的名称列是唯一的,否则您应该选择用户 ID 以清除重复项。 .map { |a| a.pop(2) } 删除结果数组中的 id。

从数据库中提取记录并对其调用.uniq是一个巨大的反模式。您正在从数据库中提取大量数据,然后在 Ruby 中整理重复项。这可能会导致严重的性能问题。

处理状态的更好方法是使用 ActiveRecord::Enum:

class Task
  enum :status, [:incomplete, :complete, :deleted]
end

这将允许您查询:

Task.incomplete
Task.completed

并为您提供了交互和突变方法:

task.complete?
task.complete!

您可以像这样使用它:

user.projects.left_joins(:tasks).where(tasks: Task.incomplete)
    .distinct
    .pluck('users.id, users.name, tasks.count')
    .map { |a| a.pop(2) }

最新更新