[[tutorials:todolist/11|Eleventh Step, Refactor with AspectHelper]] <- Prev
====== Twelfth Step, Validation and Errors ======
Right now, all kinds of things could still go wrong when you do things like creating tasks with no title at all or try to open/close a task that does not exist. So in this step we will add some little checks for these cases.
First we head over to the Controller again and take a look at #create:
def create
title = request['title']
TodoList[title] = {:done => false}
end
Here we just create a new task, no matter what we get. Every seasoned web-developer would advise you to be suspicious about all the input you receive from your users, so let's apply this advice.
def create
if title = request['title']
title.strip!
if title.empty?
failed("Please enter a title")
redirect '/new'
end
TodoList[title] = {:done => false}
end
end
First of all we check if we got a request with a value for 'title', if we get none we just let the aspect kick in that will redirect the browser to the index. Next we strip the title of all spaces around it so we can check if it is empty. We will talk about the specifics of our error-handling now.
Ramaze has a helper called FlashHelper, that will keep a hash associated with the session for one request, afterwards the hash is thrown away. This is specifically useful for giving the user feedback while keeping a stateless approach.
Let me show you our #failed method (it goes in the private section to #task_status):
def failed(message)
flash[:error] = message
end
Duh, you may say, wouldn't that fit in the one line instead of the call to #failed? Indeed, it would, but let me remind you, we have no checks for changing the status of a task yet. We will need error-handling there as well, so we just keep our code DRY and maintainable by collecting shared behaviour in small pieces.
Now on to the #task_status:
def task_status title, status
unless task = TodoList[title]
failed "No such Task: `#{title}'"
redirect_referer
end
task[:done] = status
TodoList[title] = task
end
That used to look like this:
def task_status title, status
task = TodoList[title]
task[:done] = status
TodoList[title] = task
end
So in fact all we added is a check whether a task already exists, set an error-message in case it doesn't and redirect to wherever the browser came from.
But what about actually showing the error-messages we so carefully set? Well, where do we change the view? Right, in the templates. But both templates we have so far (index and new) share this behaviour, so we head over to the Element and add in the right place:
#{@title}
\#{flash[:error]}
#{content}
The only thing special about it is the \#{flash[:error]}, we have to escape the # so it won't evaluate this immediately but wait until it is really rendered. As a note, If you read this as pure markaby, the double backslash is to output properly to HTML, just use one instead. Again, you can add some nifty style for that.
To be continued...
[[tutorials:todolist/11|Tenth Step, Configuration]] <- Prev