16

If I have a Client domain class, and that Client hasMany Courses. How do I find the course I'm looking for? For instance:

class Client {
    String name
    static hasMany = [courses:Course]
}

class Course {
    String name
    static belongsTo = [client:Client]
}

def client = Client.get(1)

I want to "find" or "search" within that courses relationship. Maybe something like:

client.courses.find(name:'Whatever')

Is there any way to do this with Grails?

intargc
  • 3,051
  • 5
  • 36
  • 52

2 Answers2

29

If you're using a second level cache and have configured it for this association, you might want to iterate over the collection (this will save you a database query if the association is in cache).

Here is an example using the clever Groovy Collection API:

def course = client.courses.find { it.name == "whatever" }

Important: If you decide to take this approach make sure to configure eager / batch fetching of courses so you don't run into the n+1 problem.

Community
  • 1
  • 1
Kimble
  • 7,295
  • 4
  • 54
  • 77
  • is this approach better than the next one? – Alexander Suraphel Dec 10 '13 at 07:00
  • It depends on your use case. You should really avoid using associations if it can grow without bounds, but for associations limited to a few entities ( < 10?) this will probably do just fine for a lot of use cases. – Kimble Dec 10 '13 at 09:55
  • I would recommend encapsulating the search code in a service method or in the domain class itself (as a getter method) so that you can easily try out different implementations in a benchmark with real-world data. – Tobia Jun 17 '15 at 07:51
12

One way is with dynamic finder methods:

Courses.findAllByClientAndName(client, 'whatever')

This would get all a client's courses named 'whatever'.

Grails also has few other ways to accomplish this.

ataylor
  • 64,891
  • 24
  • 161
  • 189
  • What do you do if you don't have the belongsTo setup? – monksy Apr 27 '15 at 18:14
  • 2
    You can query on the joining column instead. For example `findAllByClientIdAndName` if the `Course` object has a `clientId` property. It depends on how your domain expresses the relationship between the two objects. – ataylor Apr 27 '15 at 18:33