如何在rails模型中进行计算?
How to perform calculation in rails model?
我已经创建了项目、阶段、任务和 sub_task 个脚手架:
project
与 stage
具有一对多关联
stage
与 task
具有一对多关联
task
与 sub_task
. 具有一对多关联
stage
、task
和 sub_task
表都有一个字段 planned_end_date
和 status
.
现在我想为 projects#index
操作中的每个 project
打印直到 planned_end_date
才完成的总阶段、任务、sub_task。
如何在 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
我试过的-
项目#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>
代码的作用是打印所有项目的待处理阶段、任务和 sub_task 的总数,并为每个项目打印相同的计数。我想为每个项目的总待处理阶段+任务+sub_tasks 打印待处理阶段+任务+sub_tasks。
什么
是的,您计算的是所有项目,而不仅仅是当前项目。
你想要的是...
<% stages = Stage.where(project_id: project.id) %>
请注意,我们使用的是 project.id
,它引用每个循环中的当前项目,而不是 @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 %>
但即便如此,这也意味着项目模型需要知道是什么导致阶段不完整,如果您更改业务规则,这将是一件令人头疼的事情,因此也许可以在阶段中创建一个范围
class Stage
scope :incomplete, -> {where('planned_end_date < ?', Date.today).where(status: [0,2])}
end
并且在项目中
class Project
def incomplete_stages_count
stages.incomplete.count
end
end
我已经创建了项目、阶段、任务和 sub_task 个脚手架:
project
与stage
具有一对多关联
stage
与task
具有一对多关联
task
与sub_task
. 具有一对多关联
stage
、task
和 sub_task
表都有一个字段 planned_end_date
和 status
.
现在我想为 projects#index
操作中的每个 project
打印直到 planned_end_date
才完成的总阶段、任务、sub_task。
如何在 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
我试过的-
项目#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>
代码的作用是打印所有项目的待处理阶段、任务和 sub_task 的总数,并为每个项目打印相同的计数。我想为每个项目的总待处理阶段+任务+sub_tasks 打印待处理阶段+任务+sub_tasks。 什么
是的,您计算的是所有项目,而不仅仅是当前项目。
你想要的是...
<% stages = Stage.where(project_id: project.id) %>
请注意,我们使用的是 project.id
,它引用每个循环中的当前项目,而不是 @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 %>
但即便如此,这也意味着项目模型需要知道是什么导致阶段不完整,如果您更改业务规则,这将是一件令人头疼的事情,因此也许可以在阶段中创建一个范围
class Stage
scope :incomplete, -> {where('planned_end_date < ?', Date.today).where(status: [0,2])}
end
并且在项目中
class Project
def incomplete_stages_count
stages.incomplete.count
end
end