2016-12-20 3 views
0

私は、単純なhasManyの関連付けだと思ったものを持っている - のUserGroup hasManyのユーザ、およびUserGroupには、ユーザーが所有しています:Grails 3 beforeInsert()関連する挿入を停止しない?

class UserGroup { 

    String name 
    User owner 
    Set members = [] 
    static hasMany = [members: User] 
    ... 
} 

ファイン今のところ。私はその名前が所有者ごとに一意であることを望んでいたので、もともと名前に制約を置いていました:

name unique: 'owner' 

しかし、これによって同じ名前の更新もできませんでした。だから私はbeforeInsertに制約を移動し、expicitlyロジックを実行します。

def beforeInsert() { 
    boolean existing = false 
    UserGroup.withNewSession { 
     existing = UserGroup.where { 
      owner == this.owner && name == this.name 
     }.count() > 0 
    } 
    if (existing) { 
     this.errors.rejectValue(...) 
    } 
    return !this.hasErrors() 
} 

メンバーと新しいのUserGroupオブジェクトを保存し、beforeInsertは渡し、私はA)のUserGroupを挿入する休止アクションはその後、b)のメンバーを挿入見ます。

新しいUserGroupオブジェクトをメンバーとともに保存し、beforeInsertが重複した名前で失敗すると、メンバーを挿入するための休止状態のアクションだけが表示されます。親レコードがないので、これはもちろん失敗します。

私は間違ったことをやっているのですか?それとも、beforeInsertはsave()操作の一部を殺すだけで、すべてのものではないのですか?そして何をすべきか?

+0

答えとして、(正しく)発行された更新が一意性制約に違反しないので、特別なコードは必要ありません。問題は消えていますが、beforeInsert()の動作はまだ疑問です。 – Jay

+0

メンバーを持つ新しいUserGroupオブジェクトを保存し、beforeInsertが '重複した名前のために失敗する '場合、これは'親レコードがないので失敗します.' ...なぜ親はありませんか?あなたが提案したように、それはbeforeInsertによって 'duplicate'としてキャッチされたからです。あなたの現在の質問に価値があるかどうか不明です。たとえそれが複製であることができない親を持っていたとしても、今のように1の代わりに両方のテーブルをロールバックしなければならないからです – Vahid

答えて

0

beforeInsertのコードはカスタムバリデーター上にあるはずですが、固有の名前をチェックしていますので、右の制約は名前が一意でなければなりません:true(「owner」は一意ではありません、値がスペックhttps://docs.grails.org/latest/guide/validation.htmlのようにブールべきである)

そして、あなたがいる場合、ドキュメントhttps://docs.grails.org/latest/ref/Database%20Mapping/cascade.html

に指定されたマッピングフィールドで指定することができ、カスケードに保存するグループ内のユーザーにしたい場合カスタムバリデータが失敗するか、またはユニークなものだけが失敗すると、カスケードセーブ/アップデートは実行されません。

関連する問題