Rethinkdb 和 Thinky 如何在具有 'hasMany' 关系的模型中保存多个模型,其中父模型包含子模型数组
Rethinkdb and Thinky how to saveAll on multiple models in a model that has a 'hasMany' relationship where parent model contains array of child models
这个问题很难说清楚,但可以。最终,我在 RethinkDB 中有一组模型,它们以一种链模式相互关联。当我想使用用 "hasMany" 关系定义的字段时,我遇到了一个问题,使用 Thinky ORM,将一组 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);
});
});
这是一个使用 Reqlite 模拟 RethinkDB 数据库的测试用例,thinky 作为 ORM,mocha 作为测试套件来 运行 测试。在代码示例中,最后一个原型 id: '320'
和名称 Jack-O-Trades
是遇到问题的那个,其他两个构建良好。问题是,只有 jackBuildNode
与 skill
模型的正确关联被保存。 Jack-O-Trades
上nodes
数组中的第二个节点jackDebugNode
在数据库中保存并创建,但没有保存该节点与skillDebugging
技能模型应有的关系.
谁能看出我这里的代码 and/or 逻辑可能哪里出错了?我知道有一些方法可以通过模块化保存和更新关系来解决这个问题,但是让单个 saveAll() 操作负责关联和创建此数据会更安全,因为单个操作在没有损坏的情况下更有可能成功,因为将其分解为多个 save/update 调用会产生不完整 saves/updates 的可能性。任何见解将不胜感激。
将此问题作为问题发布到 thinky github 后,我收到了作者在问题中描述的解决方案。对于那些可能在这里寻找答案的人,问题的总结是这样的:
没有传递参数的 .saveAll() 方法被作者描述为 弃用 并且应该始终指定要保存的关系以获得 .saveAll () 方法正确递归。查看 .saveAll() 中传递的参数的 thinky docs 并查看 neumino 发布的修改后的代码示例,了解如何稍微修改此代码示例以插入 saveAll 参数并保存正确的关系。
这个问题很难说清楚,但可以。最终,我在 RethinkDB 中有一组模型,它们以一种链模式相互关联。当我想使用用 "hasMany" 关系定义的字段时,我遇到了一个问题,使用 Thinky ORM,将一组 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);
});
});
这是一个使用 Reqlite 模拟 RethinkDB 数据库的测试用例,thinky 作为 ORM,mocha 作为测试套件来 运行 测试。在代码示例中,最后一个原型 id: '320'
和名称 Jack-O-Trades
是遇到问题的那个,其他两个构建良好。问题是,只有 jackBuildNode
与 skill
模型的正确关联被保存。 Jack-O-Trades
上nodes
数组中的第二个节点jackDebugNode
在数据库中保存并创建,但没有保存该节点与skillDebugging
技能模型应有的关系.
谁能看出我这里的代码 and/or 逻辑可能哪里出错了?我知道有一些方法可以通过模块化保存和更新关系来解决这个问题,但是让单个 saveAll() 操作负责关联和创建此数据会更安全,因为单个操作在没有损坏的情况下更有可能成功,因为将其分解为多个 save/update 调用会产生不完整 saves/updates 的可能性。任何见解将不胜感激。
将此问题作为问题发布到 thinky github 后,我收到了作者在问题中描述的解决方案。对于那些可能在这里寻找答案的人,问题的总结是这样的:
没有传递参数的 .saveAll() 方法被作者描述为 弃用 并且应该始终指定要保存的关系以获得 .saveAll () 方法正确递归。查看 .saveAll() 中传递的参数的 thinky docs 并查看 neumino 发布的修改后的代码示例,了解如何稍微修改此代码示例以插入 saveAll 参数并保存正确的关系。