Как выполнить расчет в модели рельсов? - PullRequest
1 голос
/ 09 марта 2020

Я создал проекты, этапы, задачи и подзадачи:

  • project имеет связь один-ко-многим с stage
  • stage имеет связь один-ко-многим с task
  • task имеет связь один-ко-многим с sub_task.

stage, task и sub_task таблиц имеют все поля planned_end_date и status.

Теперь я хочу напечатать итоговые этапы, задачи, подзадачи, которые не выполнены до planned_end_date для каждого project в projects#index action.

Как я могу это сделать в модели Rails?

class Project < ApplicationRecord
  has_many :stages, dependent: :destroy
  validate :end_after_start

  private
  def end_after_start
    return if to_date.blank? || form_date.blank?

    if to_date < form_date
      errors.add(:to_date, "Project end date must be same or after the start date")
    end
  end
end

что я пробовал -

project # index. html .erb

      <% @projects.each do |project| %>
        <tr>
          <td><%= project.project_name %></td>

          <%  @stages = Stage.where(project_id: @projects.ids) %>
          <%  @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 =0 %>
          <%  @count = stage_counter + task_counter + sub_task_counter %>

          <td><span class="alert"><%= @count.to_s + " Activity Pending" %></span></td>

то, что делает код, печатает общее количество ожидающих этапов, задач и подзадач для всех проектов и печатает одинаковое количество для каждого проекта. Я хочу напечатать ожидающие этапы + задачи + подзадачи для всех ожидающих этапов каждого проекта + задачи + под_задачи. то, что

1 Ответ

3 голосов
/ 09 марта 2020

Да, вы рассчитываете на ВСЕ проекты, а не только на текущий проект.

То, что вы хотите ...

<% stages = Stage.where(project_id: project.id) %>

обратите внимание, что мы используем project.id который ссылается на текущий проект в каждом l oop, а не @projects, который является всеми проектами.

Лучше может быть ...

<% stages = project.stages %>

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

<% stage_counters = project.stages.where('planned_end_date < ?', Date.today).where(status: [0,2]).count %>

Если вы Собираетесь выполнять сложные логические тесты, это помогает использовать скобки, чтобы убедиться, что вы получили правильный порядок приоритета,

<%  @stages.each{|s| stage_counter += 1 if (s.planned_end_date.past? && s.status == 0) || (s.planned_end_date.past? && s.status == 2)} %>

Вы можете сделать то же самое с задачами и подзадачами, определив отношения в модель ...

has_many :stages, dependent: :destroy
has_many :tasks, through: :stages
has_many :sub_tasks, through: :tasks

Это позволит вам сделать project.tasks и project.sub_tasks

Обратите внимание, что вы можете переместить эти вычисления в модель ...

class Project

  def incomplete_stages_count
    stages.where('planned_end_date < ?', Date.today).where(status: [0,2]).count
  end

Что лучше и позволит вам сделать ...

<% project.incomplete_stages_count %>

, но даже тогда это означает, что модель проекта должна знать, что делает стадию незавершенной, что является головной болью, если вы когда-нибудь измените бизнес-правила, так что, возможно, создайте область в Stage

class Stage
  scope :incomplete, -> {where('planned_end_date < ?', Date.today).where(status: [0,2])}
end

И в Project

class Project
  def incomplete_stages_count
    stages.incomplete.count
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...