Jeff's Blog

Musings about software development, Java, OO, agile, life, whatever.


Tuesday, February 03, 2009 
Convention and Case

I'm learning Grails. I found a good tutorial written by Jason Rudolph. It does a great job of covering a broad range of the typical things you'd want to do in putting up a quick web site.

Unfortunately, it's for an older version of Grails, but so far that hasn't been a barrier; most of the changes I need to make are self-explanatory. I'm almost finished, and feel I have a good grasp on using Grails.

Still, I struggled for about two hours last night on a problem in going through the tutorial. Here's a form I defined.

<g:form controller="user" method="post">
    ...
    <g:actionSubmit value="Log In"/>
    ...
</g:form>
And here's some of the controller:
class UserController extends BaseController {
  def beforeInterceptor =
 [action:this.&auth, except: ['login', 'logout']]

  def index = { redirect(action:list,params:params) }

  def allowedMethods = [delete:'POST', save:'POST', update:'POST']

  def login = {
   // ... 
  }
  // ...
}
I think that's all that's relevant to show. Those of you who know Grails know how the form knows which controller method to call; I wasn't paying enough attention and missed the simple cause of my problem, which was that a simple form submit from the login page kept generating a 404, URL not found. It showed me the request URI:
RequestURI=/racetrack/user/index
Yet that is a valid URI (index redirects, of course). In fact, if I copied the URL grails generated, and pasted it into the address bar, the proper page came up. I tried a few things, including explicitly specifying the action:
<g:form controller="user" method="post" action="login">
No dice, same problem:
HTTP ERROR: 404

NOT_FOUND

RequestURI=/racetrack/user/login
Well, frustrated, I tried a few other things. No dice. I looked at the HTML provided in the book and looked to ensure I typed it correctly (I almost always type my own sample code rather than paste it, I learn better that way). Looks pretty much the same. Web search, no exact match on my same problem; found a couple odd things that it might be, tried 'em, not the problem.

When in doubt, really make sure you have exactly the same thing. Whitespace and case. Case couldn't possibly matter on button text, could it? Well, yes, especially when you follow this notion of programming by convention or programming by default or whatever you want to call it. An actionSubmit defines the controller method, either explicitly or implicity. Explicity, you can simply say:

<g:actionSubmit value="Log In" action="login"/>
In the absence of the action attribute, it uses the value attribute. Apparently, it lowercases the first letter for you, but then simply removes spaces, not lower-casing any subsequent letters. Thus it was looking for a controller action named "logIn," apparently. The tutorial code has it typed as "Log in." I typed it "Log In" (I thought it looked nicer). Harumph.

Dumb on my part, for not paying enough attention to how the form was supposed to figure out which controller method to call (I hadn't figured this out yet, and thought this was another "by convention" element, perhaps from somewhere else). Dumb on Groovy's part, for not showing me the URI with the improper casing.

Lesson for me: Pay more attention. Lesson for tools that play by convention: if you're going to do something as clever as use button text to define an action, make sure you are picky about case everywhere, and make it clear from whence that action name came (i.e. better error messages). Lesson for tutorial writers: It's hard work to write a good tutorial. A good one gets you through all the happy path circumstances. A great one helps you out with all the dumb mistakes you'll inevitably make.


Comments:
The problem you had, makes me think, that tools are as good as their ability to help you solve encountered problem.
 
Post a Comment

Links to this post:

Create a Link



<< Home

RSS Feed (XML)

Archives

February 2004   March 2004   May 2004   September 2004   October 2004   January 2005   February 2005   September 2005   October 2005   November 2005   December 2005   January 2006   February 2006   March 2006   June 2006   August 2006   January 2007   February 2007   March 2007   April 2007   September 2007   October 2007   November 2007   December 2007   January 2008   February 2008   March 2008   April 2008   May 2008   June 2008   July 2008   August 2008   September 2008   October 2008   November 2008   December 2008   January 2009   February 2009   March 2009  

This page is powered by Blogger. Isn't yours?