2016-06-23 1 views
1

非常に難しい問題ですが、ここには入ります。最終的に私はRethinkDB内に一連のチェーンパターンで互いに関係する一連のモデルを持っています。 Thinky ORMを使用して "hasMany"関係で定義されたフィールドを使用してrethinkdbモデルの配列を配置してデータベースに保存し、オブジェクトとの関係を作成するときに問題が発生しています。Rethinkdbと思考方法親モデルに子モデルの配列が含まれている 'hasMany'関係を持つモデルの複数のモデルに複数のモデルを保存する方法

これは段落で説明するのが非常に難しく、時間がかかるので、コードで、私が直面している問題を説明するために、独立したテストケースを作成しました。

var Reqlite = require('reqlite'); 
var assert = require('assert'); 

var thinky = require('thinky')({ 
    "host": "localhost", 
    "port": 28016, 
    "db": "test" 
}); 

var server = new Reqlite({"driver-port": 28016}); 

var r = thinky.r; 
var type = thinky.type; 


// Models 
var Account = thinky.createModel('accounts', { 
    id: type.string(), 
    username: type.string(), 
}); 

var User = thinky.createModel('users', { 
    id: type.string(), 
    name: type.string(), 
    accountId: type.string(), 
    archetypeId: type.string(), 
}); 

var Archetype = thinky.createModel('archetypes', { 
    id: type.string(), 
    name: type.string(), 
}); 

var Node = thinky.createModel('nodes', { 
    id: type.string(), 
    skillId: type.string(), 
    archetypeId: type.string(), 
}); 

var Skill = thinky.createModel('skills', { 
    id: type.string(), 
    name: type.string(), 
    desc: type.string(), 
}); 


// Relationships 
// Account <--> User 
Account.hasMany(User, 'users', 'id', 'accountId'); 
User.belongsTo(Account, 'owner', 'accountId', 'id'); 

// User <--> Archetype 
User.belongsTo(Archetype, 'archetype', 'archetypeId', 'id'); 

// Archetype <--> Node 
Archetype.hasMany(Node, 'nodes', 'id', 'archetypeId'); 
Node.belongsTo(Archetype, 'archetype', 'archetypeId', 'id'); 

// Node <--> Skill 
Node.belongsTo(Skill, 'skill', 'skillId', 'id'); 
Skill.hasMany(Node, 'nodes', 'id', 'skillId'); 


before(function(done) { 

    var skillDebugging = Skill({ 
     id: '100', 
     name: 'Debugging', 
     desc: 'Increase knowledge of the inner working of things', 
    }); 
    var skillBuilding = Skill({ 
     id: '110', 
     name: 'Building', 
     desc: 'Survive the Apocalypse with this', 
    }); 

    var debuggerNode = Node({ 
     id: '200', 
     skill: skillDebugging, 
    }); 

    var builderNode = Node({ 
     id: '210', 
     skill: skillBuilding, 
    }); 

    var jackBuildNode = Node({ 
     id: '220', 
     skill: skillBuilding, 
    }); 
    var jackDebugNode = Node({ 
     id: '230', 
     skill: skillDebugging, 
    }); 

    var archetype1 = Archetype({ 
     id: '300', 
     name: 'Debugger', 
     nodes: [debuggerNode], 
    }); 
    var archetype2 = Archetype({ 
     id: '310', 
     name: 'Builder', 
     nodes: [builderNode], 
    }); 
    var archetype3 = Archetype({ 
     id: '320', 
     name: 'Jack-O-Trades', 
     nodes: [jackBuildNode, jackDebugNode], 
    }); 

    archetype1.saveAll().then(function(result) { 
     archetype2.saveAll().then(function(result1) { 
      archetype3.saveAll().then(function(result2) { 
       done(); 
      }).error(done).catch(done); 
     }).error(done).catch(done); 
    }).error(done).catch(done); 
}); 

describe('New Test', function() { 
    it('should return a list of archetypes with all joined nodes and skills', function(done) { 
     Archetype.getJoin().then(function(archetypes) { 
      // here we should expect to see the data saved and joined in each archetype as it was defined 
      // above in the "before" block 
      console.info('\nList of archetypes: ', JSON.stringify(archetypes)); 
      assert.ok(archetypes); 

      archetypes.forEach(function(archetype) { 
       assert.ok(archetype); 
       assert.ok(archetype.nodes); 
       archetype.nodes.forEach(function(node) { 
        assert.ok(node); 
        assert.ok(node.skill); 
       }); 
      }); 
      done(); 
     }).error(done).catch(done); 
    }); 

    it('should return a skill with a list of nodes joined', function(done) { 
     Skill.get('100').getJoin().then(function(debugSkill) { 
      console.info('\nDebug skill JSON: ', JSON.stringify(debugSkill)); 
      // if successful, we should see two nodes associated with this skill 
      assert.ok(debugSkill); 
      assert.ok(debugSkill.nodes); 
      assert.ok(debugSkill.nodes.length > 1); 
      done(); 
     }).error(done).catch(done); 
    }); 
}); 

これは、テストを実行するテストスイートとしてORMとしてシンキー、RethinkDBデータベースをシミュレートするためにReqliteを使用し、そしてモカテストケースです。コード例では、最後のアーキタイプid: '320'と名前Jack-O-Tradesが問題を経験していますが、他の2つはうまくいきます。問題は、skillモデルとの適切な関連付けで保存されているのはjackBuildNodeのみです。第2ノードjackDebugNodenodesアレイにあり、Jack-O-Tradesに保存され、データベースに作成されますが、ノードがskillDebuggingスキルモデルで持つ必要がある関係は保存されません。

ここでコードやロジックでどこが間違っているのか誰にでも見えますか?私は、節約をモジュール化し、後で関係を更新することでこれを回避する方法があることを理解していますが、単一のsaveAll()操作で単一操作以来このデータの関連付けと作成を担当する方がずっと安全です複数の保存/更新呼び出しを分割すると、不完全な保存/更新の可能性が生じるため、破損することなく成功する可能性が高くなります。どんな洞察力も大変高く評価されます。

答えて

0

thinky githubでこの問題を投稿した後、私はこの問題に記載されている解決策を著者から受け取りました。

パラメータが渡されずに使用されるthinky。saveAll()メソッドは、と記述されており、作成者によって非推奨のと記述されています。 .saveAll()メソッドを適切に再帰させるために保存する必要があります。 .saveAll()で渡されたパラメータのthinky docsをチェックし、neuminoによってポストされた変更されたコードサンプルをチェックして、このコードサンプルがsaveAllパラメータを挿入して適切な関係を保存する方法を少し変更したか確認してください。

関連する問題