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/indexYet 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/loginWell, 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.
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