Consider the following class:
Class Timesheet {
BigDecimal hoursWorked
Boolean reviewedByCustomer
Boolean approvedByCustomer
...
}
The timesheet can have three states in terms of customer review:
- TO_BE_CHECKED (
reviewedByCustomer == false && approvedByCustomer == null
) - APPROVED (
reviewedByCustomer == true && approvedByCustomer == true
) - DENIED (
reviewedByCustomer == false && approvedByCustomer == false
)
I want to use an enum type ReviewStatus
to represent these states that can be retrieved from a timesheet or used to update the timesheet. The two boolean values shall not be used anymore. With the following parameter map: [reviewStatus:'APPROVED']
, data binding should work as follows .
def timesheet = new Timesheet(params)
or
bindData(timesheet, params)
The Status should be checked as follows:
if(timesheet.reviewStatus == ReviewStatus.TO_BE_REVIEWED){
//do Logic
}
To achieve this behaviour, I use a transient property and getter and setter methods:
...
//reviewStatus does only exist as getter and setter methods, not as fields
static transients = ['reviewStatus']
ReviewStatus getReviewStatus(){
if(reviewedByCustomer == false && approvedByCustomer == null){
ReviewStatus.TO_BE_REVIEWED
} else if(reviewedByCustomer == true && approvedByCustomer == true){
ReviewStatus.APPROVED
} else if(reviewedByCustomer == true && approvedByCustomer == false){
ReviewStatus.DENIED
}
}
void setReviewStatus(ReviewStatus reviewStatus){
if(reviewStatus == ReviewStatus.TO_BE_REVIEWED){
reviewedByCustomer = false
approvedByCustomer = null
} else if(reviewStatus == ReviewStatus.APPROVED){
reviewedByCustomer = true
approvedByCustomer = true
} else if(reviewStatus == ReviewStatus.DENIED){
reviewedByCustomer = true
approvedByCustomer = false
}
}
...
However, it does not work. Not even with bindable:true
. I found this as an answer for similar questions, but they seem to have been using an earlier version of Grails. The only way I could get it to work was by using bindData(object, params, [exclude:[]])
. I assume that the empty map prevents the transient properties from being added to the exclusion list automatically.
I would prefer to use the bindable constraint instead, because this would be a cleaner solution than passing an empty map every time I bind data to a timesheet
Using Grails 2.4.2.
EDIT 1: Using Grails 2.4.2 data binder, not spring data binder.