0

抽象クラスを使用して Grails ドメイン モデルを定義しようとしています。相互に 1 対 1 の双方向関係を持つ 2 つの抽象クラスを定義する必要があり、それらを機能させることができません。

ドキュメントの Face-Nose の例に基づく説明:

私はこの例を実装し、期待どおりに動作するテストを作成しました。関係の終わりを設定すると、grails はもう一方の端を設定します。

class Face {
    static hasOne = [nose:Nose]

    static constraints = {
        nose nullable: true, unique:true
    }
}

class Nose {
    Face face
    static belongsTo = [Face]

    static constraints = {
        face nullable:true
    }
}


    when:'set a nose on the face'
        def testFace = new Face().save()
        def testNose = new Nose().save()

        testFace.nose = testNose
        testFace.save()

    then: 'bidirectional relationship'
        testFace.nose == testNose
        testNose.face == testFace

これら 2 つのクラスを抽象クラスとして宣言し、2 つの具象サブクラス (ConcreteFace と ConcreteNose 属性なし) で同じテストを繰り返すと、2 番目のアサーションは false になります: testNose.face は null です。

私は何か間違ったことをしていますか?そうでない場合、どうすれば抽象ドメイン クラスの関係を因数分解できますか?

4

1 に答える 1

0

必要以上の save() があり、Nose 内のロジックが間違っています。まず、Faceクラスはそのままで問題ありません。ここに貼り付けて完成させましょう:

class Face {

   static hasOne = [nose:Nose]

   static constraints = {
      nose nullable:true, unique: true
   }
}

次に、

class Nose {

   static belongsTo = [face:Face]

   static constraints = {
   }
}

ここで、属している関係を取得すると、制約セクションで(親) をnull 許容にすることはできないことに注意してください。

最後に、統合テストです。単なる単体テストではなく、統合テストであることを確認してください。統合テストは、単体テストで行われる ops のモックだけでなく、データベース関連のロジック (CRUD ops) をテストするときにも必要です。ここ:

def "test bidirectionality integration"() {
   given: "a fresh face and nose"
   def face = new Face()
   def nose = new Nose(face:face)
   face.setNose(nose)

   when: "the fresh organs are saved"
   face.save()

   then: "bidirectionality is achieved"
   face.nose == nose
   nose.face == face
}

ここで、の保存さえ必要ないことに注意してください。を保存すると、すでにが残っています。face.save() の後にステートメントnose.save()追加しても、ここでは何も得られませんが、前ではありません。親がテーブルにうまく収まる前に子を保存することはできません。

それを行うと、次のいずれかが得られます。

|Tests PASSED - view reports in ...
于 2015-05-11T15:27:14.180 に答える