我正在构建一个 Rails 4.2+ 应用程序,它具有Workflows
和Tasks
. Atask.due_date
可以是指定的日期(例如“01/01/2017”),也可以是相对于父workflow
记录上的日期。
class Workflow < ApplicationRecord
# closing_date:date
after_save :update_relative_tasks
has_many :tasks
# Production code would make sure closing_date changed before updating associations
def update_relative_tasks
tasks.where(has_relative_date: true).each do |task|
task.update_relative_due_date(closing_date)
end
end
end
class Task < ApplicationRecord
# due_date:date
# has_relative_date:boolean (default: false)
# number:integer (default: 0)
# days_or_weeks:string (default: "days")
# before_or_after:string (default: "after")
# workflow:references
belongs_to :workflow
def number_of_days
@number_of_days ||= if days_or_weeks == "weeks"
number * 7 # relative date is in "weeks"
else
number # assume relative date is in "days"
end
end
# Pseudo-ish code, not tested, but shows concept
def update_relative_due_date(date)
new_due_date = if before_or_after == "before"
date - number_of_days.days
else
date + number_of_days.days
end
update_attribute(:due_date, new_due_date)
end
end
在上分配特定日期task
很简单,我只使用日历小部件并设置日期,没问题。
棘手的部分是task.due_date
根据workflow.closing_date
.
例如,假设workflow.closing_date
我01/01/2017
想要在该日期之前(或之后)5 天到期的任务。
我可以添加一些执行类似操作的表单字段,其中括号表示输入字段:
Due Date: [x] number of [days|weeks] [before|after] workflow.closing_date
然后我可以在 Ruby 代码中解析出来并task
用正确的due_date
.
但是,如果workflow.closing_date
发生更改,我将需要查找所有相关联tasks
并重新计算它们的相对日期。此外,如果workflow.closing_date
最初不知道并且后来添加了它,则它再次需要重新计算所有相关任务的截止日期。
最终,我还将向 中添加提醒tasks
,这些提醒也将与task.due_date
. 非常类似于 Google 日历的通知工作方式。
这样的事情是如何解决的?我知道我需要添加一个后台处理器来处理发送提醒。但我不确定如何解决task.due_date
在另一条记录上设置相对于某个日期的问题。