2012-07-14 19 views
5

मुझे एक समस्या है जहां मेरी डोमेन क्लास में दो संभावित परस्पर अनन्य बाहरी कुंजी हैं, या तो एक सीरियल नंबर या विरासत लुकअप मान।Grails डोमेन क्लास में दो फ़ील्ड के लिए मैं कैसे और XOR सत्यापन बना सकता हूं?

चूंकि मुझे यकीन नहीं है कि मेरे पास किसी भी प्रविष्टि के लिए कौन सा होगा, मैंने उन्हें यह सुनिश्चित करने के लिए कस्टम और सत्यापन किया है कि मेरे पास एक और केवल एक मूल्य है।

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)) 
     } 
    } 
} 

मैं डिफ़ॉल्ट CRUD स्क्रीन बनाया है और इस डोमेन वर्ग

information: Blah Blah 
serialNumber: 
legacyLookup: BLAHINDEX123 

यह निम्न संदेश के साथ सत्यापनकर्ता में मर जाता है के लिए एक प्रवेश बनाने की कोशिश की:

No such property: serialNumber for class: myproject.Sample 

मैं क्या कर रहा हूँ लापता?

उत्तर

9

प्रत्येक संपत्ति में कई बार आवश्यक नहीं है; वास्तव में आपको केवल उनमें से एक को वास्तव में बाध्य करने की आवश्यकता है। इसके अलावा आप सीधे उनके नाम से गुणों का संदर्भ नहीं दे सकते हैं। ऐसे ऑब्जेक्ट्स हैं जो बाधा बंद करने के लिए पास की जाती हैं जिनका उपयोग मूल्यों पर प्राप्त करने के लिए किया जाता है (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... 

आप बाधा से कुछ भी वापस जाने के लिए अगर कोई त्रुटि है की जरूरत नहीं है ...

+0

यह वही किया जो मुझे चाहिए था। मैं सोच रहा था कि मुझे दोनों क्षेत्रों पर स्पष्ट रूप से सत्यापन की आवश्यकता है, लेकिन एक दूसरे को संभालता है। धन्यवाद! – GeoGriffin

0

यदि आप यह सुनिश्चित करना चाहते हैं कि आपके पास "एक और एक ही मूल्य" है तो दूसरा विकल्प serialNumberLegacyLookup नामक एक सामान्य क्षेत्र बनाना होगा जो serialNumber और legacyLookup फ़ील्ड दोनों का प्रतिनिधित्व करेगा। फिर आप legacyLookup नामक अपने डोमेन क्लास में एक बूलियन फ़ील्ड जोड़ सकते हैं जो false पर डिफ़ॉल्ट होगा। फिर आप सत्यापनकर्ता के माध्यम से मूल्य चला सकते हैं और यह देख सकते हैं कि यह "धारावाहिक संख्या" या "विरासत लुकअप" मान था या नहीं। यदि मान "लीगेसी लुकअप" मान बन गया है तो आप legacyLookup बूलियन true पर सेट करेंगे। मुझे लगता है कि यह दृष्टिकोण एक यूआई परिप्रेक्ष्य से कम भ्रमित होगा (उपयोगकर्ता के लिए केवल दो फ़ील्ड दो सशर्त क्षेत्रों के बजाय भरने के लिए)।

+0

चूंकि मैं बाहरी विरासत प्रणाली के साथ बातचीत के साथ काम कर रहा हूं, मुझे नहीं लगता कि यह समाधान उचित है। मेरे पास आने वाले डेटा में एक फ़ील्ड या दूसरा है, लेकिन उन्हें अद्वितीय फ़ील्ड के रूप में मॉडलिंग किया गया है। ऐसे कुछ व्यवसाय नियम हो सकते हैं जो इस समय मेरे लिए अज्ञात हैं जो मॉडल की मेरी समझ को तोड़ सकता है। खुद को उस संभावना से अलग करने के लिए, मैं उन्हें अलग रखने जा रहा हूं। – GeoGriffin

0

मैं इस एक ही परिदृश्य और समाधान मैंने पाया का सामना करना पड़ा एक गेटर विधि बना सकते हैं और एक बाधा को जोड़ने के लिए था इसके लिए

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) 
    } 
}