Javascript 反思DB和Thinky如何在一个具有';有许多';父模型包含子模型数组的关系

Javascript 反思DB和Thinky如何在一个具有';有许多';父模型包含子模型数组的关系,javascript,rethinkdb,thinky,Javascript,Rethinkdb,Thinky,这是一个很难明确表达的问题,但接下来是。最终,我在RejectionDB中有一组模型,它们以某种链式模式相互关联。当我想使用Thinky ORM,使用一个定义了“hasMany”关系的字段,将一组数据库模型放入数据库,保存到数据库中,并创建与对象的关系时,我遇到了一个问题 由于在段落中解释这一点非常困难和冗长,我创建了一个单独的测试用例,用代码来说明我所面临的问题 var Reqlite = require('reqlite'); var assert = require('assert');

这是一个很难明确表达的问题,但接下来是。最终,我在RejectionDB中有一组模型,它们以某种链式模式相互关联。当我想使用Thinky ORM,使用一个定义了“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);
    });
});
var-Reqlite=require('Reqlite');
var assert=require('assert');
var thinky=require('thinky')({
“主机”:“本地主机”,
“港口”:28016,
“db”:“测试”
});
var server=new-Reqlite({“驱动程序端口”:28016});
var r=thinky.r;
变量类型=thinky.type;
//模型
var Account=thinky.createModel('账户'{
id:type.string(),
用户名:type.string(),
});
var User=thinky.createModel('用户'{
id:type.string(),
名称:type.string(),
accountId:type.string(),
archetypeId:type.string(),
});
var Archetype=thinky.createModel('archetypes'{
id:type.string(),
名称:type.string(),
});
var Node=thinky.createModel('节点'{
id:type.string(),
skillId:type.string(),
archetypeId:type.string(),
});
var Skill=thinky.createModel('skills'{
id:type.string(),
名称:type.string(),
desc:type.string(),
});
//关系
//帐户用户
hasMany(用户,'users','id','accountId');
User.belongsTo(帐户,'owner','accountId','id');
//用户原型
User.belongsTo(原型,'Archetype','archetypeId','id');
//原型节点
hasMany(Node,'nodes','id','archetypeId');
Node.belongsTo(原型,'Archetype','archetypeId','id');
//节点技能
Node.belongsTo(Skill,'Skill','skillId','id');
hasMany(Node,'nodes','id','skillId');
之前(功能(完成){
var skilldebug=Skill({
id:'100',
名称:“调试”,
描述:“增加对事物内在运作的认识”,
});
var skillBuilding=技能({
id:'110',
名称:"大厦",,
desc:“用它来度过世界末日”,
});
var debuggerNode=Node({
id:'200',
技能:熟练调试,
});
var builderNode=节点({
id:'210',
技能:技能建设,
});
var jackBuildNode=Node({
id:'220',
技能:技能建设,
});
var jackDebugNode=节点({
id:'230',
技能:熟练调试,
});
var archetype1=原型({
id:'300',
名称:“调试器”,
节点:[调试节点],
});
var archetype2=原型({
id:'310',
名称:'Builder',
节点:[builderNode],
});
var archetype3=原型({
id:'320',
名称:“Jack-O-Trades”,
节点:[jackBuildNode,jackDebugNode],
});
archetype1.saveAll().then(函数(结果){
archetype2.saveAll().then(函数(result1){
archetype3.saveAll().then(函数(结果2){
完成();
}).错误(完成)。捕获(完成);
}).错误(完成)。捕获(完成);
}).错误(完成)。捕获(完成);
});
描述('新测试',函数(){
它('应返回包含所有连接节点和技能的原型列表',函数(完成){
getJoin().then(函数(原型){
//在这里,我们应该看到在每个原型定义时保存和连接的数据
//在“之前”块中
console.info('\n原型列表:',JSON.stringify(原型));
assert.ok(原型);
原型。forEach(函数(原型){
assert.ok(原型);
assert.ok(原型.nodes);
archetype.nodes.forEach(函数(节点){
assert.ok(节点);
assert.ok(node.skill);
});
});
完成();
}).错误(完成)。捕获(完成);
});
它('应该返回一个技能并加入一个节点列表',函数(完成){
Skill.get('100').getJoin().then(函数(debugSkill){
console.info('\nDebug skill JSON:',JSON.stringify(debugSkill));
//如果成功,我们将看到与此技能相关的两个节点
assert.ok(debugSkill);
assert.ok(debugSkill.nodes);
assert.ok(debugSkill.nodes.length>1);
完成();
}).错误(完成)。捕获(完成);
});
});
这是一个使用Reqlite模拟数据库的测试用例,thinky作为ORM,mocha作为测试套件来运行测试。在代码示例中,最后一个原型,
id:'320'
和name
Jack-O-Trades
,是遇到问题的原型,而其他两个原型都很好地解决了问题。问题是,只有
jackBuildNode
skill
模型正确关联后才能保存。第二个节点,
Jack-O-Trades
上的
nodes
数组中的
jackDebugNode
保存并在数据库中创建,但不保存该节点应与
skilldebuging
技能模型的关系


有人能看到我在这里的代码和/或逻辑中可能出错的地方吗?我确实明白,我可以通过模块化保存和更新后续关系来解决这个问题,但使用单个saveAll()会安全得多操作负责关联和创建此数据,因为单个操作更可能成功而不会损坏,因为将其拆分为多个保存/更新调用可能会导致保存/更新不完整。如果您有任何见解,我们将不胜感激。

将此问题发布为