2016-04-01 23 views
0

İki etki alanı sınıfı var CGroup ve Directory, Çok sayıda Dizin bulunan bir CGroup modellemek istiyorum, ancak bu birçok dizinden biri "root" olarak bilinir ve doğrudan CGroup'dan erişilebilir. Herhangi bir CGroup'un yalnızca bir kökü olmalıdır ve kaskadlar, herhangi bir dizinin silinmesinin tüm çocuklarını sileceği şekilde çalışmalıdır. Yanlış rağmenGORM örneğin bir hasMany ilişkisinde GORM doğrudan erişim

, bu şimdiye kadar ne var:

class CGroup{ 
    ... 
    Directory root 

    static hasMany = [directory:Directory] 

    static constraints = { 
     root(unique:true) 
    } 
} 

class Directory { 

    static hasMany = [children:Directory] 
    ... 
    static belongsTo = [parent:Directory, 
         cgroup:CGroup] 

    static constraints = { 
     parent nullable: true 
    } 
} 

temelde, sadece "bir" tarafında saklanan "çok" koleksiyonundan bir örneği başvurusu, ihtiyaç

cevap

1

Bunu birkaç farklı yolla denedim ve çalışmayı başarabilmemin tek yolu, root'un geçici olarak geçersiz hale getirilmesine izin vermekti. Ben bu olmadan vardı sorunu sipariş nedeniyle oldu - Directory örnekleri hasMany içinde CGroup kaydedilene kadar kaydedilemez veya kayıt() cgroup null olduğundan başarısız olur (addToDirectory çağıran bu ayarlanır). Ancak, null olmayansa, root özelliğini ayarlayarak CGroup'u kaydedemezsiniz.

Yani null root yapılmış ama root boşsa doğrulama başarısız özel doğrulayıcı eklendi ve herhangi örnekleri hasMany içinde vardır:

static constraints = { 
    root nullable: true, validator: { Directory root, CGroup cgroup -> 
     if (!root && cgroup.directory?.size()) { 
     return ['root.required'] 
     } 
    } 
} 

Yani herhangi gerekli değerlerle ve olmadan CGroup örneği kurtaracağını herhangi bir ilişkili Directory örneği. Sonra addToDirectory ile Directory örneklerini eklemek ve özel setter ile root örneği ayarlayın:

void setRoot(Directory root) { 
    if (this.root) { 
     removeFromDirectory this.root 
    } 

    if (root) { 
     addToDirectory root 
    } 

    this.root = root 
} 

ve tekrar kaydedin:

def group = new CGroup(...).save() 

group.root = new Directory(...) 
group.addToDirectory(new Directory(...)) 
group.addToDirectory(new Directory(...)) 
group.save() 

g1.errors 
+0

Evet! tam olarak aradığım şey buydu, belirttiğiniz sipariş sorunu tam olarak karşılaştığım sorundu ama ben özel validators ile çok aşina değildim. Ayrıca, oldukça yaygın bir senaryo gibi göründüğünden belli bir şeyi kaçırmış olabileceğimi düşündüm. Bir şey, son kod bloğunuzda ikinci addToDirectory aslında setRoot için bir çağrı olmamalıdır? Alkışlar – Alexjjsmith

+1

Hayır, kök önce ayarlanır ve ardından toplam 3 için iki ek örnek eklenir. Sipariş, ikinci kez kaydetme() işlevini çağırdığınız sürece önemli değildir, kök ayarlanır ve bu örnekte bulunur. hasMany, isteğe bağlı olarak bazı ek örneklerle birlikte. –