How to create and XOR check for two fields in a Grails domain class?

I have a problem when my domain class has two potential mutually exclusive foreign keys: a serial number or an outdated search value.

Since I'm not sure which one I will have for any given entry, I made them both nullable and added a custom check to make sure that I have one and only one value.

package myproject 

class Sample {

    String information
    String legacyLookup
    String serialNumber

    static constraints = {
        information(nullable: true)
        legacyLookup(nullable: true)
        serialNumber(nullable: true)

        legacyLookup validator: {
            return ((serialNumber != null && legacyLookup == null) || (serialNumber == null && legacyLookup != null))
        }

        serialNumber validator: {
            return ((serialNumber != null && legacyLookup == null) || (serialNumber == null && legacyLookup != null))
        }
    }
}

I created a default CRUD screen and tried to create an entry for this domain class

information: Blah Blah
serialNumber: 
legacyLookup: BLAHINDEX123

This dies in the validator with the following message:

No such property: serialNumber for class: myproject.Sample

What am I missing?

+5
source share
3 answers

; . . , , (. docs). , , , :

class Sample {
    String information
    String legacyLookup
    String serialNumber

    static constraints = {
        information(nullable: true)
        legacyLookup(validator: {val, obj->
            if( (!val && !obj.serialNumber) || (val && obj.serialNumber) ) {
                return 'must.be.one'
            }
        })
    }
}

messages.properties :

must.be.one=Please enter either a serial number or a legacy id - not both

- :

legacyLookup(validator: {val, obj->
    if(!val && !obj.serialNumber) {
         return 'must.be.one'
    }
    if(val && obj.serialNumber) { 
         return 'only.one'
    }
})

message.properties:

only.one=Don't fill out both
must.be.one=Fill out at least one...

, ...

+9

, " ", serialNumberLegacyLookup, serialNumber, legacyLookup. legacyLookup, false. , , " " " ". " ", legacyLookup boolean true. , ( ).

0

, , , , getter .

package myproject 

class Sample {

    String information
    String legacyLookup
    String serialNumber

    def getTarget(){
        if (legacyLookup && !serialNumber) {
            return legacyLookup
        } else if (!legacyLookup && serialNumber) {
            return serialNumber
        } else {
            return null
        }
    }

    static constraints = {
        information(nullable: true)
        legacyLookup(nullable: true)
        serialNumber(nullable: true)
        target(nullable: false)
    }
}
0
source

All Articles