GGizmos
GGizmos

Reputation: 3775

Grails unique constraint on Domain list

If I have a domain Person and a Domain Hobby, and Person hasMany Hobby, how can I make sure the same Hobby isn't added more than once to the Person collection.

i.e. something like

`

   class Hobby {
      String name
      static belongsTo = [person: Person] 
   }
   class Person
      String name

      static hasMany =[hobby: Hobby]

      static constraints= {
        hobby.name unique: true           //like this
      }
   }   

Upvotes: 2

Views: 885

Answers (3)

Joshua Moore
Joshua Moore

Reputation: 24776

This is the prefect use case for a custom validator. I suggest reading the documentation so you get a feeling for what is possible with one, but you could use something like this:

class Hobby {
   String name
   static belongsTo = [person: Person]
}
class Person
   String name

   static hasMany = [hobby: Hobby]

   static constraints = {
      hobby validator: { val, obj ->
         if (obj.hobby.find{ (it.name.equals(val.name) && it.id != val.id) } ) return ['unique']
      }
   }
}

The above is just something off the top of my head, there may be typos or logic errors, but it's an example of how you can implement your own check using a custom validator.

UPDATE Gregg's answer about making the Hobby unique per Person is actually a much simpler and cleaner way to address this. As he points out there is actually no need for a custom validator since the relationship exists between Person and Hobby.

Upvotes: 0

Gregg
Gregg

Reputation: 35864

I know this has been answered but the easiest way is really to do this:

class Hobby {
  String name
  static belongsTo = [person: Person] 

  static constraints = {
    name unique: 'person'
  }
}

This will ensure that a hobby has a unique name per it's parent, person. No need for a custom validator.

Upvotes: 6

Stefan Urbansky
Stefan Urbansky

Reputation: 148

The documentation (http://docs.grails.org/2.5.5/guide/GORM.html#sets,ListsAndMaps) says that a collection defined with hasMany is a java.util.Set. And a Set cannot contain duplicates.

So I think you don't have to define a constraint and you have your requested behavior by default.

Upvotes: -1

Related Questions