Filtering Grails Objects that have hasMany relationships

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.