2012-07-14 51 views
5

我有一個問題,我的域類有兩個潛在的互斥外部鍵,序列號或傳統查找值。如何爲Grails域類中的兩個字段創建和異或驗證?

因爲我不確定哪一個我會有任何給定的條目,我已經讓他們都可以爲空,並添加自定義驗證,以確保我有一個且只有一個值。

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 2012-07-15 02:21:17

0

如果你想確保你有「唯一的一個值」,另一個選擇是製作一個名爲serialNumberLegacyLookup的通用字段,它將代表serialNumberlegacyLookup字段。然後,您可以將一個布爾型字段添加到您的域名類legacyLookup,該域默認爲false。然後,您可以通過驗證程序運行該值,並解析它以查看它是否爲「序列號」或「傳統查找」值。如果該值成爲「傳統查找」值,那麼您將legacyLookup布爾值設置爲true。我認爲這種方法從UI角度來看不會讓人困惑(只有一個字段供用戶填寫,而不是兩個條件字段)。

+0

由於我正在使用的代碼與外部遺留系統交互,我認爲這種解決方案並不合適。收到的數據有一個字段或另一個字段,但它們被建模爲獨特的字段。可能有一些我現在未知的業務規則可能會破壞我對該模型的理解。爲了讓自己遠離這種可能性,我會把他們分開。 – GeoGriffin 2012-07-15 02:19:49

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) 
    } 
} 
相關問題