2013-04-24 23 views
5

Tôi đang sử dụng grails 2.2.1 và cố gắng xác thực cấu trúc lệnh lồng nhau. Đây là một phiên bản đơn giản của các đối tượng lệnh của tôi:grails xác thực đối tượng lệnh lồng nhau không hoạt động

@Validateable 
class SurveyCommand { 

    SectionCommand useful 
    SectionCommand recommend 

    SurveyCommand() { 
     useful = new SectionCommand(
       question: 'Did you find this useful?', 
       isRequired: true) 
     recommend = new SectionCommand(
       question: 'Would you recommend to someone else?', 
       isRequired: false) 
    } 
} 

@Validateable 
class SectionCommand { 
    String question 
    String answer 
    boolean isRequired 

    static constraints = { 
     answer(validator: answerNotBlank, nullable: true) 
    } 

    static answerNotBlank = { String val, SectionCommand obj -> 
     if(obj.isRequired) { 
      return val != null && !val.isEmpty() 
     } 
    } 
} 

Khi tôi cố gắng để xác nhận một thể hiện của SurveyCommand nó luôn luôn trả true bất kể giá trị phần và validator tùy chỉnh của tôi trong SectionCommand (answerNotBlank) không bao giờ được gọi. Từ tài liệu về grails, có vẻ như là this kind of nested structure is supported (deepValidate mặc định là true). Tuy nhiên, có lẽ quy tắc này chỉ áp dụng cho các đối tượng miền và không phải đối tượng Command? Hoặc tôi chỉ thiếu một cái gì đó ở đây?

Trả lời

4

Bạn có thể thêm một validator tùy chỉnh để đối tượng lệnh chính của bạn

@Validateable 
class SurveyCommand { 

    SectionCommand useful 
    SectionCommand recommend 

    static subValidator = {val, obj -> 
     return val.validate() ?: 'not.valid' 
    } 

    static constraints = { 
     useful(validator: subValidator) 
     recommend(validator: subValidator) 
    } 

    SurveyCommand() { 
     useful = new SectionCommand(
      question: 'Did you find this useful?', 
      isRequired: true) 
     recommend = new SectionCommand(
      question: 'Would you recommend to someone else?', 
      isRequired: false) 
    } 
} 
+0

nice! công trình lớn, tuy nhiên là có một cách DRY hơn thay vì xác định rõ ràng một ràng buộc cho mỗi tài sản phụ? –

2

Nếu bạn đang cố gắng để kiểm tra validation từ unit kiểm tra sử dụng mockForConstraintsTest() thì bạn nên đăng ký command đối tượng trong Config.groovy thay vì sử dụng @Validateable vì một hiện có Grails Bug. Tham khảo SO question/answers để biết chi tiết.

Bạn có thể đăng ký lớp validateable như sau trong Config.groovy

grails.validateable.classes = 
      [yourpackage.SurveyCommand, yourpackage.SectionCommand] 
+0

nó * có vẻ * hoạt động tốt (trong 2.2.1) để kiểm tra phương thức '.validate()' của lớp lệnh '@ Validatable' bằng cách đơn giản gọi' mockCommandObject' trước khi khởi tạo nó, ví dụ: 'mockCommandObject SurveyCommand' –

+0

Đồng ý. Đó là cách tiếp cận của tôi đối với câu hỏi/câu trả lời SO mà tôi đã đề cập trước đó. 'mockCommandObject' hoạt động nhưng' mockForConstraintsTest' không thành công. – dmahapatro

+0

ah, hiểu rồi, cảm ơn vì đã làm rõ. Rõ ràng là tôi không đọc đủ gần –

5

Đối với Grails 2.3 và sau đó tôi đã phát hiện ra rằng Cascade Validation Plugin giải quyết vấn đề này độc đáo. Nó định nghĩa một kiểu trình duyệt tính hợp lệ mới được gọi là cascade, nó thực hiện chính xác những gì bạn mong đợi. Sau khi cài đặt, ví dụ của bạn sẽ trở thành:

class SurveyCommand { 
    ... 

    static constraints = { 
     useful(cascade: true) 
     recommend(cascade: true) 
    } 
} 
Các vấn đề liên quan