2

我正在使用 node-orm2 来感受在 RESTful API 中使用的感觉。我在后端使用 Postgres 数据库。

我正在尝试对他们的文档进行变体,其中我在一个人和一个任务之间有一个 OneToMany 关系,在一个文件中包含以下内容:

应用程序.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} /人

  • {GET,POST} /任务

在数据库的初始加载时,我创建了一个 Person 实例,其任务只是为了在数据库中拥有一些东西。

我可以在localhost:4730/people上执行GET并取回加载时创建的人及其任务(真棒):

[{
    name     : "Kenny",
    surname  : "Powers",
    age      : 34,
    male     : true,
    continent: "enum1",
    data     : null,
    id       : 1,
    tasks    : [
        {
            description: "Heyo!",
            id: 1,
            person_id: 1
        }
    ]
}]

如果我在localhost:4730/tasks上执行GET ,我会按预期返回:

[
    {
        description: "Heyo!",
        id: 1,
        person_id: 1
    }
]

现在,这是我的问题的开始:

如果我使用有效负载对localhost:4730/tasks进行POST :

{
    description: "Another task",
    person_id: 1
}

然后在localhost:4730/tasks上做一个新的GET我得到了这个预期:

[{
    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
            }
        ]
    }]

我无法从可能出错的文档中解决问题。有没有人遇到过类似的问题?

谢谢。

4

2 回答 2

1

很棒的问题,我也找不到任何关于这个的问题。确定不必关闭缓存而是清除它,在通过 git 存储库后我发现了这个:

orm.singleton.clear(instance._singleton_uid);

它有效,但它很脏。可能会帮助某人。

更新:

您可以设置instance.cacheSaveCheck为true,这也将解决它!

于 2014-05-17T13:58:38.513 回答
0

我刚刚检查了这个过时的问题,发现我得到了一个风滚草徽章。不知道这是好是坏(将在一分钟内用谷歌搜索),但我会认为它很好。

无论如何,我只是玩了一些,发现了这篇文章,这导致我尝试在 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?
        }
    );

我不能说我完全理解为什么会这样,并且会尽我所能深入研究它,但很高兴它已经修复了。

我希望它可以帮助任何在这里遇到类似问题的人。我现在要去空旷的沙漠场景向我想象中的朋友炫耀我的新风滚草徽章......

于 2013-11-15T09:08:25.537 回答