как напечатать количество отложенных задач для каждой записи в приложении rails - PullRequest
0 голосов
/ 06 марта 2020

Я создал проект, этап, задачу и вспомогательную задачу sub_task. Каждый проект имеет много этапов, и каждый этап имеет много задач, и каждая задача имеет много подзадач. соответствующая таблица была сгенерирована в базе данных. поле запланированного начала и запланированной даты окончания было добавлено в таблицу stage, task и sub_task. Теперь я хочу добавить столбец проекта № индекса, который будет показывать количество ожидающих этапов + задач + подзадач вместе для каждого проекта. Я достиг этой цели в проекте # show, но не смог сделать это в проекте # 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)


    stage_counter = 0
    task_counter = 0
    sub_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}


    @count = stage_counter + task_counter + sub_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>

1 Ответ

0 голосов
/ 06 марта 2020

Если бы у нас была что-то вроде базы данных, которая хороша для подсчета строк ...

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 сделать то, что должно быть сделано с самоссылочной ассоциацией .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...