1

明確にするのが非常に難しい質問ですが、ここに行きます。最終的に、ある種の連鎖パターンで相互に関連する一連のモデルが RethinkDB にあります。Thinky ORM を使用して「hasMany」関係で定義されたフィールドを使用して、データベースに保存し、オブジェクトとの関係を作成するために rethinkdb モデルの配列を配置するときに問題が発生しています。

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

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);
    });
});

これは RethinkDB データベースをシミュレートするために Reqlite を使用し、ORM として thinky、テストを実行するためのテスト スイートとして mocha を使用するテスト ケースです。コード例では、最後のアーキタイプであるid: '320'nameJack-O-Tradesに問題が発生し、他の 2 つは正常に構築されます。問題は、 のみがモデルjackBuildNodeと適切に関連付けられて保存されることskillです。配列jackDebugNode内の 2 番目のノードは、データベースに保存および作成されますが、ノードとスキル モデルとの関係は保存されません。nodesJack-O-TradesskillDebugging

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

4

1 に答える 1

0

この質問をthinky githubの問題として投稿した後、著者から問題に記載されている解決策を受け取りました。ここで答えを探している人のために、問題の要約は次のとおりです。

パラメーターを渡されずに使用される thinky .saveAll() メソッドは、作成者によって非推奨であると説明されており、.saveAll() メソッドを適切に再帰させるために、保存するリレーションを常に指定する必要があります。.saveAll() で渡されるパラメーターに関するthinky ドキュメントを確認し、 neuminoによって投稿された修正済みコード サンプルを確認して、このコード サンプルがどのようにわずかに変更され、saveAll パラメーターを挿入し、適切なリレーションが保存されるかを確認してください。

于 2016-06-28T16:22:07.827 に答える