2010-10-14 62 views
22

這裏加上繼承屬性的限制就是我想要做什麼:如何在一個Grails域子類

class A { 
    String string 
    static constraints = { 
    string(maxSize:100) 
    } 
} 

class B extends A { 
    static constraints = { 
    string(url:true) 
    } 
} 

所以A類應該有一些約束和B應該有相同的加額外的對同一財產的限制。

我不能得到這工作,雖然我可以想像,它會與表每層次的理念衝突。

所以我試着通過引入一個帶有B類約束的Command對象來解決這個問題,這個約束可以在類B的構造函數中進行驗證。但是似乎Command對象只能在控制器中使用(grails一直說在那裏它沒有.validate()方法)。

所以我的問題是:什麼是解決這個使用Grails約束最優雅的方式(不重新實現手動驗證)?可能是...

  • 切換到Table-per-Sub-Class概念?
  • 以某種方式使命令對象在Domain類中工作?
  • 還有其他方法嗎?

編輯:它會好起來的,我來定義子類的所有限制,重複父類的不甚至有約束的約束或在父類的。但解決方案應該適用於同一父類的多個子類(具有不同的約束)。

+0

我不知道每一個約束將這種工作方式,因爲默認情況下繼承的類映射到同一個數據庫表。 因此,如果您的類C具有非空,對C.c的唯一約束,它將在整個表A上施加數據庫表約束 - 並且c字段將針對所有類存在,並且對於除C實例之外的任何其他類都將爲空。 – 2010-10-22 14:29:37

+0

是的,這就是爲什麼我帶來了每個子類的表演。 – 2010-10-23 13:45:28

回答

5

它是在2.X方式:

爲約束是一些ConstraintsBuilder執行的關閉,我想嘗試的B調用它,就像

class B extends A { 
    static constraints = { 
    url(unique: true) 
    A.constraints.delegate = delegate # thanks Artefacto 
    A.constraints() 
    } 
} 
+1

關閉。您必須首先更改'A.constraints'的委託:'A.constraints.delegate =委託'。但是,謝謝你指出我正確的方向。 – Artefacto 2013-03-06 09:04:24

+2

@Artefacto - 你將能夠發佈一個有效的答案,或編輯這個答案,使其工作?我知道其他人有這個問題。謝謝! – cdeszaq 2014-04-04 23:53:32

+0

我已經用grails 2.0.4(用grails控制檯)試過它,它不起作用,它會在A.contraints沒有代理屬性 – jneira 2017-02-24 12:02:40

1

基本上我怎麼沒看到可以辦到。

設計明智的域類實際上映射了數據庫表的結構。約束實際上會產生DB約束。所以你正在試圖製作幾個對象,這些對象會在同一個表上生成不同的約束。

我認爲,更好的方法是創建一個有約束的最簡單的子集的一個域對象,然後使用不同的命令對象微調要傳遞到該域的確切約束。

您還可以使用驗證:在約束不同對象類型的微調不同的限制(像域中的類型列,並根據不同類型做不同的驗證)。

-1

您需要重新聲明超類的約束,因爲它是靜態的clojure(靜態屬性和靜態方法不會被子類繼承),所以它沒有被GORM映射。

乾杯。