0

So I've got a couple of classes with the following relationship:

class Foo {

    Bar bar
    /* ... other fields ... */

}

class Bar {

    String name

}

In class Foo I've got a couple of named queries:

static namedQueries = {

    userFoos { user ->

        /* ... get Foos for this user ... */

    }

    limitFoos { colname, dir ->
        order(colname, dir)
    }

...which I can then chain together in a controller:

def foos = Foo.userFoos(currentUser).limit(colname, dir)

Pretty straightforward so far. The problem is when I try to sort on bar; I get the error:

could not resolve property: bar.name of: package.Foo.

Now, I also got this error when the queries were Criteria that were declared in the controller. So, I went and wrote a propertyMissing handler for Foo:

def propertyMissing(String name) {
        if (name.contains(".")) {
            def (String propertyname, String subproperty) = name.tokenize(".")
            if (this.hasProperty(propertyname) && this."$propertyname".hasProperty(subproperty)) {
                return this."$propertyname"."$subproperty"
            }
        }
    }

I don't know if this is really the best way to do it, but it did work! However, now that I've moved the query into the class as a named query, propertyMissing doesn't appear to work anymore! Is this use not supported, or am I just missing something here?

EDIT

So I tried moving the Criteria back into the controller and sure enough, the sub-property sort did not work there either! So I guess Criteria just don't support propertyMissing at all :/

To answer dmahapatro's question, I am using jQuery DataTables to present the information. Clicking on a column header does an AJAX call to a controller action with parameters to indicate which column to sort on and in which direction. Once I determine the column name, I call the named queries like so:

def foosFilteredLimited = params.sSearch ?
    Foo.userFoos(currentUser).filterFoos(params.sSearch).limitFoos(offset, max, colName, sortDir).list()
:   Foo.userFoos(currentUser).limitFoos(offset, max, colName, sortDir).list()

(filterFoos takes a search string and narrows the results of userFoos.)

Community
  • 1
  • 1
Charles Wood
  • 864
  • 8
  • 23
  • Can you exactly show how are you trying to use the named query where you get the exception? I think that is the main part of the question which is missing. – dmahapatro Mar 15 '14 at 02:58
  • Have you tried `bar { order("name") }` in your query? –  Mar 15 '14 at 03:59
  • @SérgioMichels that will definitely work. He wants to generalize the ordering for all properties of Foo. We cannot alias bar to use bar.name inside DetachedCriteria. – dmahapatro Mar 15 '14 at 13:39
  • @dmahapatro hey dude :-) How about handling the colname with dot inside the namedQuerie? We can use something like `"$atribute" { order(prop) }` –  Mar 15 '14 at 20:51
  • 1
    @SérgioMichels Yes my dear friend, that was my intention but I did not answer because I felt that was not lucid and I did not test that. Here is the answer. I feel there can be a better approach than this. Feeling lazy on a weekend. ;) – dmahapatro Mar 16 '14 at 01:40

1 Answers1

2

Try modifying limitFoos namedQuery as below and it should work. There is a caveat to it though. We cannot use bar.baz.name if required. ;)

limitFoos { column, ord ->
    def colStrs = column.tokenize(/./).toList()

    if( colStrs?.size() > 1 ) {
        "${colStrs[0]}" {
            order( "${colStrs[1]}", ord )
        }
    } else {
        order(column, ord)
    }
}
Charles Wood
  • 864
  • 8
  • 23
dmahapatro
  • 49,365
  • 7
  • 88
  • 117
  • That is the nice thing about `propertyMissing`; it appears to automatically recurse. Fortunately, I don't have any sub-sub-properties to sort on, so that should do the trick! Thanks! :) – Charles Wood Mar 17 '14 at 15:05
  • I do have a follow-up question: why use the slashes in tokenize instead of quotes? I like immediately making a list of the tokens, btw, it's definitely easier to read than multiple assignment. – Charles Wood Mar 17 '14 at 15:08
  • It's just a syntactic sugar provided by Groovy to represent slashy strings. Search for "slashy string in Groovy" you would get it. However, with this approach you would not need propertyMissing – dmahapatro Mar 17 '14 at 15:13
  • Yeah, it would just be nice if `propertyMissing` worked on Criteria, because then, e.g., `bar.baz.qux.name` would work automatically :) This solved my problem, though, thanks. – Charles Wood Mar 17 '14 at 15:22