Ruby on rails Rails 5-查询关联的名称';家长';和'的计数;儿童';
型号 用户有客户机,客户机有项目,项目有任务 我正在尝试构建一个带有[Name,Count]的数组以发送到Google图表-我已经解决了所有问题,但只有一个问题:Ruby on rails Rails 5-查询关联的名称';家长';和'的计数;儿童';,ruby-on-rails,ruby-on-rails-5,Ruby On Rails,Ruby On Rails 5,型号 用户有客户机,客户机有项目,项目有任务 我正在尝试构建一个带有[Name,Count]的数组以发送到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.un
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个条目。这实际上是这个用户的所有条目。它完全绕过了中的。有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>
“收集项目”%>
我相当确信这与我对如何质疑如此深的关联的误解有关
最终结果是我需要项目的名称,以及它有多少任务的计数
我通过在Project.ID
上加入Task
返回Project
,通过查询来实现这一点,但我不确定如何对整个集合执行此操作
(unshift的目的是因为从其他方面来看,我最终得到的结果格式是[[['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] }
使用.pull
获取列值
user.projects.left_joins(:tasks).where("tasks.completed = 0")
.distinct
.pluck('users.id, users.name, tasks.count')
.map { |a| a.pop(2) }
.pluck
的效率要高得多,因为它只查询传递给pluck的列并返回一个数组数组,而不是将一堆模型加载到内存中
# => [[1, 'Frank', 0], [2, 'Muhammad', 5], [3, 'Jane', 3]]
但是,除非您的名称列是唯一的,否则您应该选择用户id以删除重复项。.map{| a | a.pop(2)}
将删除结果数组中的id
从数据库中提取记录并对其调用.uniq
是一个巨大的反模式。您从数据库中提取了大量数据,然后在Ruby中对重复数据进行排序。这可能会导致严重的性能问题
另外,处理状态的更好方法是使用:
这将允许您查询:
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) }
已完成:[0,无]如果OP为列设置了默认值,则不需要使用
。我相信,如果删除nil
,那么它将不包括没有任何任务的项目。如果是预期情况,则左连接
也可以更改为连接
。不,因为您正在执行左外部连接
行即使它们在联接中没有任何匹配项,也将返回。我猜它可能是一个命名错误的枚举,或者是一个不正确定义为整数的布尔列。在这两种情况下,它都应该有一个默认值,因为您不需要空值/不确定状态。@max我不这么认为,因为。其中(…)
将影响这一点,除非您提供或nil
选项。但无论如何都存在问题。因此,我已将答案更改为连接(“左外连接…”)
选项:-)我想您的意思是“和任务。已完成=0”
Edited,我意识到您需要选择users.id
以获得正确的不同查询。否则结果将按名称显示,因此具有相同名称和计数的两个用户将作为同一行而不是两行返回。感谢您的深入思考。Task。completed
实际上是一个枚举,出于某种原因,我将完全忘记了助手。出于某种原因,我也没有想到要提取多个列(我不知道它构建了一个数组)不要命名枚举完整-命名为state或status或其他任何东西,但不要出错。
user.projects.left_joins(:tasks).where(tasks: Task.incomplete)
.distinct
.pluck('users.id, users.name, tasks.count')
.map { |a| a.pop(2) }