我已经生成了一个项目,阶段,任务和子任务支架。每个项目都有很多阶段,每个阶段都有很多任务,每个任务都有很多子任务。相应的表已在数据库中生成。计划开始日期和计划结束日期字段已添加到阶段,任务和sub_task表中。现在,我想在project#index上添加一列,以显示每个项目的暂挂阶段+任务+子任务的数量。我已经在project#show中实现了这个目标,但是我无法在project#index中做到这一点...
projects_controller.rb
def index
@projects = current_user.projects.all.order("created_at DESC").paginate(page: params[:page], per_page: 15)
end
def show
@project = Project.includes(stages: {tasks: {sub_tasks: {sub_sub_tasks: :sub_three_tasks}}}).find(params[:id])
@stages = @project.stages
@tasks = Task.where(stage_id: @stages.ids)
@sub_tasks = SubTask.where(task_id: @tasks.ids)
@sub_sub_tasks = SubSubTask.where(sub_task_id: @sub_tasks.ids)
@sub_three_tasks = SubThreeTask.where(sub_sub_task_id: @sub_sub_tasks.ids)
stage_counter = 0
task_counter = 0
sub_task_counter = 0
sub_sub_task_counter = 0
sub_three_task_counter = 0
@stages.each{|s| stage_counter += 1 if s.planned_end_date.past? && s.status == 0 || s.planned_end_date.past? && s.status == 2}
@tasks.each{|s| task_counter += 1 if s.planned_end_date.past? && s.status == 0 || s.planned_end_date.past? && s.status == 2}
@sub_tasks.each{|s| sub_task_counter += 1 if s.planned_end_date.past? && s.status == 0 || s.planned_end_date.past? && s.status == 2}
@sub_sub_tasks.each{|s| sub_sub_task_counter += 1 if s.planned_end_date.past? && s.status == 0 || s.planned_end_date.past? && s.status == 2}
@sub_three_tasks.each{|s| sub_three_task_counter += 1 if s.planned_end_date.past? && s.status == 0 || s.planned_end_date.past? && s.status == 2}
@count = stage_counter + task_counter + sub_task_counter + sub_sub_task_counter + sub_three_task_counter
end
index.html.erb(项目)
<table>
<thead>
<tr>
<th>Project Name</th>
<th>Activity Status</th>
</tr>
</thead>
<tbody>
<% @projects.each do |project| %>
<tr>
<td><%= project.project_name %></td>
<td class="alert"><%= @total_count.to_s + " Activity Pending" %></td>
</tr>
<% end %>
</tbody>
</table>
如果只有像数据库这样的东西可以很好地统计行数...
class Project < ApplicationRecord
has_many :stages
has_many :tasks, through: :stages
def self.with_counts
# subquery to fetch a count of the stages
stages = Stage
.where('stages.project_id = projects.id')
.where('stages.planned_end_date < ?', Time.current)
.select('COALESCE(COUNT(*), 0)')
.where(status: [0,2])
# subquery to fetch a count of the tasks
tasks = Task
.joins(:stage)
.select('COALESCE(COUNT(*), 0)')
.where(status: [0,2])
.where('tasks.planned_end_date < ?', Time.current)
.where('stages.project_id = projects.id')
select(
"projects.*",
"(#{stages.to_sql}) + (#{tasks.to_sql}) AS total_count"
).group(:id)
end
end
这将执行单个查询,并通过子查询选择total_count
:
SELECT projects.*,
(SELECT COALESCE(COUNT(*), 0)
FROM "stages"
WHERE ( stages.project_id = projects.id )
AND ( stages.planned_end_date < '2020-03-06 15:14:01.936655' )
AND "stages"."status" IN ( 0, 2 ))
+ (SELECT COALESCE(COUNT(*), 0)
FROM "tasks"
INNER JOIN "stages"
ON "stages"."id" = "tasks"."stage_id"
WHERE "tasks"."status" IN ( 0, 2 )
AND ( tasks.planned_end_date < '2020-03-06 15:14:01.941389' )
AND ( stages.project_id = projects.id )) AS total_count
FROM "projects"
GROUP BY "projects"."id"
ORDER BY "projects"."id" ASC
LIMIT $1
我什至不打算碰您的'SubTask'类,因为那是FUBAR尝试使用self referential association应该做什么。