Reputation: 882
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
.)
Upvotes: 0
Views: 96
Reputation: 50265
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)
}
}
Upvotes: 2