observe this task closely

written by mark on February 6th, 2008 @ 05:44 AM

I have a number of task lists that each contains a number of tasks [one to many] that may be active or complete. If all of the tasks are complete then I want to mark the task list as complete. I would like to know which task lists are complete without having to perform a join on the task table and count them each time I load the index page.

Instead I will keep track of each time a task is created, deleted, changed from active to complete or changed from complete back to active state. Then I can just look for task lists that have an ‘active task count’ of 0.

It sounded tough at first and I tried a number of different ways but eventually came up with a way to do it in 26 lines of elegant code and touching only one file.

The amazing part (to me) is that code below is 100% complete and requires no changes to the to the TaskList class or the Task class which means that there is no worrying that someone will forget to update the task list count.

Also the entire thing can be turned off by commenting out the very last line “TaskObserver.instance” and nothing will break.


class TaskObserver < ActiveRecord::Observer
  def after_initialize(task)
    task.orig_complete = task.complete
  end

  def after_update(task)
    if task.orig_complete != task.complete
      if task.complete == true
        task.task_list.decrement(:active_tasks_count).save
      else
        task.task_list.increment(:active_tasks_count).save
      end
    end
  end

  def after_create(task)
    task.task_list.increment(:active_tasks_count).save
  end

  def after_destroy(task)
    task.task_list.decrement(:active_tasks_count).save unless task.complete?
  end

end

TaskObserver.instance

Post a comment