Node.js orm2 - проблема с поиском новых ассоциаций в отношениях OneToMany

Я играю с node-orm2, чтобы понять, каково это использовать в RESTful API. Я использую базу данных Postgres на сервере.

Я пытаюсь изменить их документы, где у меня есть отношение OneToMany между человеком и задачей со следующим в одном файле:

app.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} / задачи

При начальной загрузке БД я создаю экземпляр Person с задачей просто иметь что-то в БД.

Я могу сделать GET на localhost:4730/people и вернуть человека, созданного во время загрузки, с его задачей (потрясающе):

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

Если я сделаю GET на localhost:4730/tasks, я вернусь, как и ожидалось:

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

Теперь вот начало моей проблемы:

Если я делаю POST для localhost:4730/tasks с полезной нагрузкой:

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

И затем сделать свежий GET на localhost:4730/tasks, я получаю это, как и ожидалось:

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

Теперь, выполняя новый GET для localhost: 4730 / чел., Можно было бы ожидать, чтобы показать две задачи, назначенные для person_id 1 (Кенни Пауэрс), но, увы, ассоциация, похоже, зарегистрирована на многих сторонах, но не на одной стороне отношений:

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

Я не могу работать из документов, где я могу пойти не так. Кто-нибудь сталкивался с подобными проблемами?

Благодарю.

2 ответа

Решение

Я только проверял этот несвежий вопрос и увидел, что получил за это значок. Не уверен, хорошо это или плохо (погуглю через минуту), но я восприму это как хорошее.

Во всяком случае, я просто поиграл с этим еще немного и нашел этот пост, который заставил меня попробовать отключить кеш (true по умолчанию) в модели Person.

Таким образом, все работает, если в модели 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?
        }
    );

Я не могу сказать, что полностью понимаю, почему это работает, и буду стараться изо всех сил, но рад, что это исправлено.

Я надеюсь, что это поможет любому приземлиться здесь с подобной проблемой. Я собираюсь показать мой новый значок ватной палочки моим воображаемым друзьям в пустой пустынной сцене...

Удивительный вопрос, я тоже ничего не мог найти по этому поводу. Решив, что не нужно отключать кэширование, а вместо этого очистить его, пройдя через git-репозиторий, я обнаружил следующее:

orm.singleton.clear(instance._singleton_uid);

Это работает, но довольно грязно. Может помочь кому-то, хотя.

Обновить:

Вы можете установить instance.cacheSaveCheck к истине, и это также исправит это!

Другие вопросы по тегам