Inside my Player domain class, I am attempting to use the dynamically generated findByNumber method inside the custom validator for number to find an existing Player instance with the same number. The complete domain class is below.
When I run my Grails app and purposefully try to create a new player using the generated scaffolding web page, the following exception is thrown:
Class: groovy.lang.MissingMethodException
Message: No signature of method: com.sciotofootball.Player.findByNumber() is applicable for argument types: (java.lang.Integer) values: [15]
Is is permissible to use dynamically generated findBy methods inside a custom validator?
class Player {
// Min and max values
static final MIN_GRADE = Holders.config.player.grade.min.toInteger()
static final MAX_GRADE = Holders.config.player.grade.max.toInteger()
static final MIN_NUMBER = Holders.config.player.number.min.toInteger()
static final MAX_NUMBER = Holders.config.player.number.max.toInteger()
static final MIN_WEIGHT = Holders.config.player.weight.min.toInteger()
static final MAX_WEIGHT = Holders.config.player.weight.max.toInteger()
// This pattern matches as follows
// Feet (5 or 6)-Inches (0-12)
static final HEIGHT_PATTERN = "[56]\\-(([0-9]{1})|([12]{1}[0-1]{1}))"
// Valid football positions
static final VALID_POSITIONS = [
// Offense
"QB", "RB", "WR", "TE", "OL",
// Defense
"DL", "LB", "DB",
// Special teams
"P", "K"
]
Integer number;
String firstName;
String lastName;
Integer grade;
String position1;
String position2;
String height;
Integer weight;
static constraints = {
// unique: true adds unique index to the player table
// number nullable: false, unique: true, min: MIN_NUMBER, max: MAX_NUMBER
number nullable: false, min: MIN_NUMBER, max: MAX_NUMBER, validator: { numberValue ->
Player existingPlayer = findByNumber( numberValue )
return ( existingPlayer == null ?: [ 'unique', existingPlayer.firstName, existingPlayer.lastName ] )
}
firstName blank: false
lastName blank: false
grade nullable: false, range: MIN_GRADE..MAX_GRADE
position1 blank: false, inList: VALID_POSITIONS
position2 nullable: true, inList: VALID_POSITIONS, validator: { position2Value, player ->
// Position 2 cannot be equal to position 1
return ( player.position1 != position2Value ?: [ 'duplicate' ] )
}
height blank: false, matches: HEIGHT_PATTERN
weight nullable: false, min: MIN_WEIGHT, max: MAX_WEIGHT
}
}