views:

213

answers:

3

Hi, I have the following Domain Class:

 class Metric {

   String name
   float value

   static belongsTo = [Person,Corporation]

   static indexes = {
    name()
 }
}

How can I add a constraint so Person,Corporation and name are unique ?

Thanks.

A: 

I think this should work..add this to Metric. Obviously you can ignore the nullables if you want.

static constraints = {
        name(blank:false)
        corporation(nullable:false)
        person(nullable:false)

        name(unique:['corporation','person'])
    }

I tested with this integration test and it seemed to work.

def newCorp = new Corporation(name:"Corporation1")
newCorp.save()
def newPerson = new Person(name:"Person1")
newPerson.save()

def newMetric = new Metric(name:"Metric1",corporation:newCorp,person:newPerson)
newMetric.save()

newMetric = new Metric(name:"Metric1",corporation:newCorp,person:newPerson)
newMetric.save()

assertTrue (Metric.list().size == 1)
Steven Dorfmeister
However there might be the same name used for different corporations or groups.
Tiggerizzy
A: 

Here's a link to a similar situation, slightly different. But pretty close. Might give you another good idea on how to do this.

http://johnrellis.blogspot.com/2009/09/grails-constraints-across-relationships.html

Gregg
A: 

Before I proceed with my answer I want to caveat that with Grails 1.2.x (possibly 1.3.x as well) compound unique constraints are broken if any of the values can be null. If you cannot live without unique behavior you can use a custom validation to do the trick. See: https://cvs.codehaus.org/browse/GRAILS-5101

The proper way to accomplish having your Metric domain class be unique within name, person, and corporation.

class Metric {

  String name
  float value
  Person person
  Corporation corporation

  static belongsTo = [person: Person, corporation: Corporation] 

  static indexes = {
    name()
   }

  static constraints = {
    name(unique:['person', 'corporation'])
    person(unique:['name', 'corporation'])
    corporation(unique:['name', 'person'])
  }
}

You will need to call out person and corporation as members of your model. You could even drop the static belongsTo if you do not care about cascading delete behavior.

In the above example, name must be unique in person and corporation; person must be unique in name and corporation, and finally corporation must be unique in name and person.

Tiggerizzy