In Grails (using GORM), querying objects based on the properties of nested associations (a hasMany relationship) requires nested closures inside the criteria query. Here's a quick explanation of how to filter Grails objects that have a hasMany relationship with tags.
The GORM Criteria Query
The code below demonstrates how to fetch a list of Posts owned by a specific user that also contain any of the tags in a given collection. We use a nested closure block targeting the association postTags and query it using the 'in' restriction:
def Posts[] postsList = Posts.withCriteria {
eq ( 'user', userObj )
postTags {
'in' ('name', userFilter.postsTags.toArray()*.name )
}
}
Key Concept
The spread operator *.name is a Groovy shorthand that extracts the name property of every element in the userFilter.postsTags collection and returns them as a flat list. GORM compiles this criteria query into a SQL statement containing an inner join on the tag association table, filtered with a SQL IN clause.