tags:

views:

270

answers:

3

I'm very new to grails (day 2).

First, I find it hard to find easily browsable resources (the documentation is very raw, and the tutorials are spread out and only show 'hello world' types of examples ).

I've set up my domain class with a relationship to other data types.

class ShopCategoryPage{
//some stuff
ProductProcedure procedure;
ProductCategory category;
//some stuff
}

In my controller, I am getting a category id and a procedure id as parameters, and I am trying to get the ShopCategoryPage associated with those parameters.

How do I "find" them? I tried passing the ids as procedureId or procedure_id, I tried passing a ProductProcedure object generated by findById ...

I'm not sure how to find by a property that is not of native type.

+3  A: 

First, I find it hard to find easily browsable resources (the documentation is very raw, and the tutorials are spread out and only show 'hello world' types of examples ).

In my opinion the documentation is great, perhaps we're using different docs. I use:

If that still isn't satisfactory, I highly recommend the book "The Definitive Guide to Grails". I believe "Grails in Action" is also very good, but haven't read it. For learning Groovy, "Programming Groovy" is a great book (albeit a little out of date).

In my controller, I am getting a category id and a procedure id as parameters, and I am trying to get the ShopCategoryPage associated with those parameters.

The easiest way (though not the most efficient) is to use the dynamic finders.

// First of all load the ProductProcedure and ProductCategory 
// I'm assuming here the request params are named 'procedureId' and 'categoryId'
ProductProcedure productProcedure = ProductProcedure.get(params.procedureId.toLong())
ProductCategory productCategory = ProductCategory .get(params.categoryId.toLong())

// Now get the ShopCategoryPage associated with these. Replace 'find' with 'findAll'
// if there could be multiple associated ShopCategoryPages
ShopCategoryPage shopCategoryPage = ShopCategoryPage.findByProcedureAndCategory(productProcedure, productCategory)

A shortcoming of this approach is that it will cause 3 SELECT statements to be executed. If you're only interested in the shopCategoryPage returned by the last query, you could load this in "one shot" using HQL or a criteria query instead.

Don
About the book recommendation, it was released in Jan 2009. Is that considered too old? Or is this still a good buy?
nute
I assume you're referring to TDGTG? This book covers Grails 1.1, whereas the latest version 1.2. However, there's no book (that I'm aware of) that covers 1.2 as it was only released a few weeks ago.
Don
Thanks, just ordered it now, expedited. About your code help, see comments to Burt's answer.
nute
My mistake, I've fixed the method name. It should be `findByProcedureAndCategory`
Don
i would mark you both as "best answer" if i could ...
nute
Give it to Burt, he needs the points more than I do ;)
Don
+1  A: 

You should never use findById since it'll bypass the id-based 2nd-level cache and only use the query cache, which is a lot more volatile. Use get() instead.

Having said that, there's two ways to do this. One is to use get():

def shopCategoryPage = ShopCategoryPage.findByProcedureAndCategory(
       ProductProcedure.get(params.procedureId),
       ProductCategory.get(params.categoryId))

(use the appropriate param name for the two ids)

or using an HQL query (or a criteria query) to fetch the instance in one query instead of 3:

def shopCategoryPage = ShopCategoryPage.executeQuery(
   'from ShopCategoryPage p where p.procedure.id=:procedureId and p.category=:categoryId',
    [procedureId: params.procedureId.toLong(), categoryId: params.categoryId.toLong()])[0]
Burt Beckwith
Your answer is disturbingly similar to mine ;)Are you sure it's not necessary to call `toLong()` on the params when using the 3-query solution?
Don
Is it findByProductProcedureAndProductCategory or findByProcedureAndCategory (object type vs property name)? Either way, I am getting "No such property: procedure for class: mmh.shop.ViewCategoryController", which is weird because it talks about my controller class instead of the domain class. And also because it says "procedure" regardless of if I typed Procedure or ProductProcedure.
nute
I've fixed the method name. It should be findByProcedureAndCategory
Don
Yes it worked now. About my error message, it didn't like that I declared the category and procedure in an IF statement, my bad, now it all works (until I ask another question very soon :) )
nute
@Don - the toLong() isn't necessary for get() calls since get() figures out the type for you. HibernatePluginSupport adds the get method to the MetaClass and calls convertToType() on the parameter. It doesn't hurt to call it first though.
Burt Beckwith
+1  A: 

I agree, the easiest way is to use an dynamic finder.

In addition to 'The Definitive Guide to Grails' by Rocher and Brown, I suggest the IBM developerWorks track 'Mastering Grails' by Scott Davis.

http://www.ibm.com/developerworks/views/java/libraryview.jsp?site_id=1&contentarea_by=Java&sort_by=Date&sort_order=1&start=1&end=19&topic_by=&product_by=&type_by=All%20Types&show_abstract=true&search_by=mastering%20grails

Brandon