我正在使用node-orm2来感受一下在RESTful API中使用的感觉。我在后端使用Postgres数据库。
我正在尝试他们的文档的变体,其中我在单个文件中具有人员和任务之间的一对一关系:
应用.js
'strict'
// Based on http://blog.modulus.io/nodejs-and-express-create-rest-api
// but with my own twists!
var express = require('express');
var app = express();
var orm = require('orm');
// Helpers
var collectionize = function(target){
if(typeof target == 'Object'){
return [target];
}
return target;
};
// Configure the app with any middleware
app.use(express.bodyParser());
app.use(orm.express("postgres://rodrigomartell:password@localhost/postgres",{
define : function(db, models, next){
// Define models
models.Person = db.define("Person",
{
name : String,
surname : String,
age : Number,
male : Boolean,
continent: ["enum1", "enum2"],
data : Object
},
{
methods : {
fullName: function(){
return this.name + this.surname;
}
},
validations : {
name: orm.enforce.unique("name already taken!"),
age : orm.enforce.ranges.number(18, undefined, "under-age")
},
autoFetch : true // global eager load
}
);
models.Task = db.define("Task",
{
description: String
}
);
// Relations
models.Task.hasOne('person', models.Person, {reverse:'tasks', required: true});
// Finally drop and sync this puppy
db.drop(function(){
db.sync(function(){
console.log('All good');
// Create one Person on load
db.models.Person.create([{
name : "Kenny",
surname : "Powers",
age : 34,
male : true,
continent: "enum1"
}], function(err, items){
var person = items[0];
db.models.Task.create([{description:'Heyo!', person_id: person.id}], function(err, tasks){
console.log(err,tasks);
});
});
// Press on?
next(); // After synching, get on with the rest of the app?
},function(err){
console.log('No good', err);
});
});
}
}));
// Configure the routes and that
app.get("/people", function(req,res){
console.log('requested');
res.type('text/plain');
// req.models is a reference to models in the middleware config step
req.models.Person.find(null, function(err, people){ // There must be a neater way to findAll?
res.json(people);
});
});
app.post("/people", function(req,res){
console.log('requested');
res.type('text/plain');
req.models.Person.create(collectionize(req.body), function(err, newPerson){
if(err){
res.json({error: err});
}
else{
res.json(newPerson);
}
});
});
app.get("/tasks", function(req, res){
res.type('text/plain');
req.models.Task.find(null, function(err, tasks){ // There must be a neater way to findAll?
res.json(tasks);
});
});
app.post("/tasks", function(req, res){
res.type('text/plain');
var task = req.body;
req.models.Task.create([req.body], function(err, task){
if(err){
res.json(err);
}
else{
res.json(task);
}
});
});
// Listen up!
app.listen(4730, function(){
console.log('Listening on http://localhost:4730');
});
我已经为以下资源设置了 GET 和 POST 路由:
{获取,发布}/人
{GET,POST}/tasks
在数据库的初始加载中,我创建了一个带有任务的 Person 实例,只是为了在数据库中有一些东西。
我可以在本地主机:4730/人上做一个 GET,并取回在加载时创建的人及其任务(很棒):
[{
name : "Kenny",
surname : "Powers",
age : 34,
male : true,
continent: "enum1",
data : null,
id : 1,
tasks : [
{
description: "Heyo!",
id: 1,
person_id: 1
}
]
}]
如果我在本地主机:4730/任务上执行 GET 操作,我会按预期返回:
[
{
description: "Heyo!",
id: 1,
person_id: 1
}
]
现在,这是我问题的开始:
如果我使用有效负载向本地主机:4730/任务进行 POST 操作:
{
description: "Another task",
person_id: 1
}
然后在本地主机上执行新的 GET:4730/任务,我按预期得到:
[{
description: "Heyo!",
id: 1,
person_id: 1
},
{
description: "Another task",
id: 2,
person_id: 1
}]
现在,在 localhost:4730/people 上做一个新的 GET,人们会期望显示分配给 person_id 1 (Kenny Powers) 的两个任务,但可惜的是,该协会似乎已经在多方面注册,但不是在关系的一方:
[{
name : "Kenny",
surname : "Powers",
age : 34,
male : true,
continent: "enum1",
data : null,
id : 1,
tasks : [
{
description: "Heyo!",
id: 1,
person_id: 1
}
]
}]
我无法从文档中找出我可能出错的地方。有没有人遇到过类似的问题?
谢谢。
很棒的问题,我也找不到任何关于这个的东西。确定不必设置缓存而是清除它,在浏览 git 存储库后,我发现这个:
orm.singleton.clear(instance._singleton_uid);
它有效,但它很脏。可能会帮助某人。
更新:
您可以将instance.cacheSaveCheck
设置为 true,这也将修复它!
我只是在检查这个陈旧的问题,看到我得到了一个风滚草徽章。不确定这是好是坏(一会儿会谷歌一下),但我会把它当作好。
无论如何,我只是多玩了一下并找到了这篇文章,这导致我尝试在 Person 模型中关闭缓存(true 是默认值)。
因此,如果在 Person 模型中,在 autoFetch 之后添加一个新属性以将缓存设置为 false,则这一切都有效。它应该看起来像这样:
models.Person = db.define("Person",
{
name : String,
surname : String,
age : Number,
male : Boolean,
continent: ["enum1", "enum2"],
data : Object
},
{
methods : {
fullName: function(){
return this.name + this.surname;
}
},
validations : {
name: orm.enforce.unique("name already taken!"),
age : orm.enforce.ranges.number(18, undefined, "under-age")
},
autoFetch : true, // global eager load
cache : false // Important as otherwise it doesn't update the relationship, why?
}
);
我不能说我完全理解为什么会这样,并且会尽我所能深入研究它,但很高兴它被修复了。
我希望它能帮助任何遇到类似问题的人。我现在要去一个空旷的沙漠场景中向我想象中的朋友们炫耀我的新风滚草徽章......