Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

grails composite "unique constraint", but how?

I'm very close to a solution but anything is still wrong, hope to get help, thanks in advance.

I have a Customer domain model like:

class BoCustomer implements Serializable{

    String firstName
    String lastName
    String emailID
    Company company
}

So, I have a primary key = "id" that's okay. So further I need kind of unique constraint that "checks" the following: "only one unique email address for one company" so that inserting the same e-mail should be allowed but only for different companies. Inserting ([email protected], company-id: 1) and inserting ([email protected], company-id: 1) is not allowed, but inserting ([email protected], company-id: 1) and inserting ([email protected], company-id: 2) is allowed.

So I tried so far:

static mapping = {
    id column: "customer_id", generator: "identity"
    emailcompany composite: ['emailID', 'company'], unique: true
}

(seems to be "good", but not exactly what I want)

BUT i don't want another column, in my try called "emailcompany" - but I need something like a unique constraint.

like image 290
grailsInvas0r Avatar asked Feb 02 '23 12:02

grailsInvas0r


2 Answers

You can specify this behaviour by one of the main constraints available: unique

class BoCustomer implements Serializable{

    String firstName
    String lastName
    String emailID
    Company company

    static constraints = {
        emailID(unique: 'company')
            // OR
        company(unique: 'emailID')
    }
}

You can see the full spec of the unique constraint here http://grails.org/doc/latest/ref/Constraints/unique.html

like image 99
fredGalvao Avatar answered Feb 07 '23 20:02

fredGalvao


If you want to enforce this with a constraint, you should be able to use a custom validator so that it returns false if a BoCustmer already exists with the same emailID and company. It's been a while since I've used it, but I think something like this should work:

class BoCustomer implements Serializable{
    String firstName
    String lastName
    String emailID
    Company company

    static constraints = {
        emailID( 
            validator: { val, obj ->
                def customerWithSameEmailAndCompany = BoCustomer.findByEmailIDAndCompany(obj.emailID, obj.company)
                return !customerWithSameEmailAndCompany
            }
        )
    }
}
like image 21
Kaleb Brasee Avatar answered Feb 07 '23 21:02

Kaleb Brasee