Separate logic from view

I decided i want to change some internal logic in SupTasks. Right now tasks are completed when they have true in ‘completed’ column in database. I want them to be completed when they have tag ‘completed’.

I’v been thinking what i will have to do in order to implement this. Well, one thing will be dropping the ‘completed’ column. The bad thing is i use automatically generated getter for this column in views to determine if the task is completed or not.

Current situation

class Task < Sequel::Model
  # nothing in here, only autogenerated getter #completed
end

# ... later in template:

<% if @task.completed %>
  <span>Completed!</span>
<% end %>

Now when i drop the column the getter disappears and without modification the view will break.

Better version

This is how it should look like:

class Task < Sequel::Model
  # custom written method
  def completed?
    completed
  end
end

# ... later in template:

<% if @task.completed? %>
  <span>Completed!</span>
<% end %>

Now when i drop the column i only have to change code at one place in model. No changes in views at all.

So i refactored it here in this commit: b762ee9

It might look like not that much necessarry in such small project(only 2 changes now). But when you work on bigger projects this approach can save you some real production trouble when you overlook that 20nth place it’s used somewhere in view.

Changing the logic now doesn’t affect any view

And now when changing the logic i didn’t need to touch that view with task.completed? inside. It’s here in this commit: 07e8a4d

If you looked into the commit, i actually had to touch html form for making the task completed. And it makes me wonder, should i also change it to only point to action which knows how to make task complete instead of updating task attributes directly? What do you think?