This is part 7 of Ramaze by Example, a tutorial on web development. In Part 6: Adding Tasks, we added the ability create new tasks to our application.
So now we are able to record things that need to be done; but we have no way of marking them completed!
Modifying the view
Examining the source code delta (git checkout 7-check-off-task; git diff 6-add-task), you’ll see that I added this to our index.xhtml view:
<?r if not task.done ?> [#{ A( ' ', :href => Rs( :check_off, task.id_ ) ) }] <?r end ?>
It looks a bit convoluted, but let me explain each little bit.
I used <?r ?> to use a condition. If the task is not done yet, then we’d like to display a checkbox for users to check off the task. If the task is done, then we don’t want to show a checkbox. Note the matching end at the bottom; this makes the stuff in between if and end render only when the condition is true, as you would expect from normal Ruby code.
I’m using square brackets to “draw” a checkbox ( “[ ]” ). Following the opening bracket, we have #{, which opens up string interpolation, as per normal Ruby. Inside the interpolation, I am making a call to a built-in Ramaze method, A(). Like R and Rs, A is part of Ramaze’s LinkHelper. You use it to build links (HTML <a> tags). The first argument I pass to A is the clickable text to be displayed (the content of the <a> tag). The second argument is an attribute hash, in this case consisting simply of the href attribute for the <a> tag.
I use Rs to build the href, passing Rs the path and then an argument. If you run the code of step 7 (ruby start.rb), and browse to the site and view source, you’ll see the <a> tags that were built, including the parameters on the hrefs. Each link points to a ‘/check_off’ path, passing the task’s id number as a parameter. (I use id_ instead of id because id is reserved in Ruby 1.8. M4DBI knows that you mean id when you use id_.)
Modifying the controller
Next, we add a method to the controller to handle the browser requests that will come when users click on checkboxes.
def check_off( id ) Task[ id ].check_off redirect Rs( :/ ) end
As you might expect, I match the name of the method with the path in the links. Also, the method accepts a parameter, just like the links have a parameter on them (e.g. ‘/check_off/5′ ). Nice and intuitive.
In the method, using our model, we pull out of the database the task with the corresponding id number: Task[ id ]. Then we execute the check_off method on that task.
And when we’re done, we redirect back to the todo list.
Modifying the model
Those of you paying attention may have asked: “check_off method? What check_off method?” Your suspicion is warranted: there is no check_off method — yet.
To complete our work in this phase of the tutorial, we extend our model as follows:
def check_off self.done = true end
Although M4DBI automatically gives us read and write access to table rows via column names, sometimes we want to have more than just that basic level of functionality. You can extend a model class by adding more methods. In this case, we’ve added a method to mark a task done. Although making a method out of a simple one-liner is not strictly necessary in this case (we could have put Task[ id ].done = true directly in the controller method), this is slightly better design (discussion and debate of this are left as exercises for the readers
).
Try it!
And that’s all we need to do to add the ability to check off tasks! Try it yourself:
git checkout 7-check-off-task ruby start.rb
then browse http://localhost:9001.
We’ll round out the functionality of our app in Part 8: Deleting Tasks.
Related posts:
[...] Ramaze by Example – Part 11: Validation and Error HandlingRamaze by Example – Part 10: CosmeticsRamaze by Example – Part 9: LayoutRamaze by Example – Part 8: Deleting TasksRamaze by Example – Part 7: Checking off Tasks [...]
[...] Ramaze by ExampleRamaze by Example – Part 11: Validation and Error HandlingRamaze by Example – Part 10: CosmeticsRamaze by Example – Part 9: LayoutRamaze by Example – Part 7: Checking off Tasks [...]