Grails has an incredible amount of very useful features, amongst those the dynamic methods on domain objects. When we generate the scaffolding for a controller for a domain object we get the default list method in the controller which uses the list method on the domain object. The list method takes params as argument containing max, offset, order and sort. With this method we can already paginate through a collection of the domain objects. That’s what the scaffolding gives us for free.
But that’s not always enough. In the current system I’m working on I decided to add a boolean flag deleted on some domain objects. The reason is that I cannot allow normal users to really delete the objects from the db, so when a user deletes an object I just flag the object as being deleted, thus I can always recover it. However, I don’t want this object to appear anymore in the list. So, an easy way to achieve that is withCriteria. If you wonder what the difference is between withCriteria and createCriteria, from what I understood withCriteria is just a shorter form of createCriteria.
First, the default list method in the controller is generated by the scaffolding:
def list = {
params.max = Math.min( params.max ? params.max.toInteger() : 10, 100)
[ dataTypeInstanceList: DataType.list( params ), dataTypeInstanceTotal: DataType.count() ]
}
And that the method I first added to my domain object DataType using createCriteria:
static notDeleted(params) {
createCriteria().list(max: params.max, offset: params.offset, sort: params.sort, order: params.order) {
and {
eq('deleted', false)
}
}
}
There should be a shorter version with withCriteria which should work as good as the previous one from what I have read. I tried something like the following but the pagination didn’t work.:
static notDeleted(params) {
withCriteria {
eq('deleted', false)
}
}
It looks pretty simple but it’s pretty powerful as you can combine a lot of operator.
And below my modified list method in the controller with a modified count:
def list = {
params.max = Math.min( params.max ? params.max.toInteger() : 10, 100)
[ valueInstanceList: Value.notDeleted( params ), valueInstanceTotal: Value.countByDeleted(false) ]
}