If you've ever worked with Grails, then you know how easy it is to create domain classes which map to database tables. Similarly, it is easy to access the database via the automatically generated conroller methods that are available (create, list, delete, save, edit, show). However, if you need to perform a particular operation against the database which is not accomplished by using any of these automatically generated methods, it is still easy...but perhaps not very intuative. Once you learn how to accomplish this task then the entire power behind using hibernate and accessing your database is at your hands.
It really is as easy as 1, 2, 3 to create additional controller methods...especially if you know how to use the Groovy language itself. I will show you how to create a simple finder method which takes a parameter and searches a particular database table for the value of that parameter...then it returns the results.
As you already know, the list method for each Grails controller is already created for you...let's look at my list method for the "Test" domain class (database table):
def list = {
if(!params.max) params.max = 10
[ testList: Test.list( params) ]
}
This is all well and good, but it returns the entire dataset for the Test database table. What if I only wish to return all of the records which have foreign key id of 35? Let's say that our foreign key id variable is fkId to make it simple. So what we want is to return all members of the list returned using the "list" method above which have fkId == 35.
We need to first obtain the complete list of results, and then filter it out accordingly. This is where the power of Groovy comes into play. We could use Java and write a filter so that we iterate through each of the items in the complete list of results searching for instances where fkId == 35 and then adding those matching objects to another list. That would be lots of code though. Let's use a Groovy closure to accomplish the same thing. Take a look at the "find" method which does just that:
def find = {
def testList = Test.list( params)
[testSearch : testList.findAll{it.fkId == Integer.valueOf(params.fkId)}]
}
Ok, simplicity at it's finest! We first obtain the complete list from the database table into the testList object. Then, we use the Groovy "findAll" method to search that list for all instances where fkId == the value of our parameter which is passed in (params.fkId)...let's assume that the parameter equals 35. We store our results in the testSearch list.
Now, how do we access this method? Well, we have to create a Groovy Server Page named find.gsp to show our results. We also need to pass the fkId parameter to this method somehow. Here is a simple find.gsp which will iterate through all of the objects which are returned within the testSearch list. Of course...this is just a quick page with ugly results...but you can clean it up to suit your needs.
find.gsp:
<g:each in="${testSearch}" status="i" var="test">
FieldOne: ${test.fieldOne}
FieldTwo: ${test.fieldTwo}
</g:each>
Now, what is the URL which we use in order to access our new controller and page? Assume that our application name is "site" and we are passing a parameter of fkId = 35...
http://localhost:8080/site/test/find?fkId=35
Easy enough, but it took me a bit of time to figure out when I first tried it. Hopefully this post will save you some time and get you adding some much needed functionality to your standard Grails app.