下面的模型怎么样Task
:
class Task < ActiveRecord::Base
belongs_to :project
def after_save(task)
self.project.finish_date = self.finish_date
end
end
项目的finish_date
将设置为任务的finish_date
. 代码假设,当前保存的任务总是finished_date
和其他任务一样。这是一个错误的假设,只需添加适当的if
语句:)
编辑
我从评论中的建议是使用Task
上面列出的内容并像这样覆盖finish_date
setter Project
:
class Project < ActiveRecord::Base
has_many :tasks
def finished_date=(new_finish_date)
self[:finish_date] = new_finish_date if self[:finish_date] < new_finish_date
end
end
由于我是从头开始编码的,因此我不确定在此之后是否应该保存项目实例。也许update_attributes
在 setter 中使用可能是一个更好的主意。
关于这里的其他解决方案
@Joelios 解决方案建议了我所做的,只是没有覆盖设置器。问题在于,Rails 包含的方法总是使用 setter(偶数update_attributes
和create
)。因此,您必须自己调用update_task_date
可能会忘记的方法。
@saverios 解决方案建议使用 Observer/Observable 模式。因此,正如我所见,它将成为其所有对象Project
的观察者。Task
当 aTask
发生变化时,它会调用它的所有观察者,即它的项目,它本身会更新它的finish_date
. 这与我仅使用设计模式所建议的不太一样,因此变得更加困难。
另一个可以考虑的解决方案是定义一个新函数update
,比如Project
遍历所有连接的任务,寻找最新的finish_date
. update
每当任务更新时,都必须调用该方法。这将是一个非常糟糕的设计,因为 n 个任务之一的每次更新都会触发 n 个数据库查询并减慢一切。
希望对面临同样问题的人有所帮助。