2015-04-13 5 views
0

У меня проблема с сохранением некоторых данных в Mongo с использованием мангуста.Mongoose не сохраняет данные при их сохранении

В моем модуле базы данных, что я делаю:

self.addMove = function (gameId, move, callback) { 
    Game.findById(gameId, function (err, game) { 
     if (err) 
     callback(err); 
     else { 
     game.newMove = move; //apply new move 
     game.save(Game.transformState(callback)); //save the game 
     } 
    }); 
    }; 

где newMove определяется как виртуальный метод в GameSchema, как

GameSchema.virtual('newMove').set(function (move) { 
    if (move.player !== move.piece[0]) 
    return; 
    if (allowedMove(move)) { //if piece is allowed to move 
    var from = positionToIndex(move.from), 
     to = positionToIndex(move.to); 
    this._field[to] = this._field[from]; //move it 
    this._field[from] = ""; 
    } 
}); 

и transformState как статический метод

GameSchema.statics.transformState = function (callback) { 
    return function (err, data) { 
    if (err) 
     callback(err); 
    else 
     callback(null, { 
     _id: data._id, 
     moves: data.moves, 
     field: data.field //data.field transforms 1D array into 2D client-useable array 
     }); 
    }; 
}; 

Как Я звоню addMove:

socket.on('addMove', function (msg) { 
    console.log('New move: ' + msg); 
    var msg = JSON.parse(msg); 
    db.addMove(msg._id, msg.move, function (err, data) { 
    if(!err) 
     io.emit('getState', JSON.stringify(data)); 
    }); 
}); 

В соответствии с просьбой, мой GameSchema:

GameSchema = new Schema({ 
    moves: [MoveSchema], 
    _field: { 
    type: [String], 
    default: ["WR", "WN", "WB", "WQ", "WK", "WB", "WN", "WR", "WP", "WP", "WP", "WP", "WP", "WP", "WP", "WP", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "BP", "BP", "BP", "BP", "BP", "BP", "BP", "BP", "BR", "BN", "BB", "BQ", "BK", "BB", "BN", "BR"] 
    } 
}) 

И в качестве бонуса, это то, как я прошу состояние игры во второй раз:

//sockets.js 
socket.on('getState', function (msg) { 
    console.log('User requested game state!'); 
    var msg = JSON.parse(msg); 
    db.getGame(msg._id, function (err, data) { 
    if(!err) 
     io.emit('getState', JSON.stringify(data)); 
    }); 
}); 

//database.js 
self.getGame = function (id, callback) { 
    Game.findById(id, Game.transformState(callback)); 
}; 

Как вы можете видеть, каждый раз, когда я получаю новый переходите от клиента, я изменяю текущее поле игры и сохраняю эту игру. Когда я сохраняю его с game.save(Game.transformState(callback));, он «сохраняется», что означает, что данные в обратном вызове верны. Но если я попытаюсь снова запросить состояние игры, я вижу, что он не сохраняется. Я также попытался проверить MongoDB вручную и действительно не был сохранен. Я пытаюсь объяснить, что в строке game.save(Game.transformState(callback)); функция callback выполнена с обновленным состоянием игры, и я могу видеть ее на клиенте, но состояние на самом деле не сохраняется в базе данных.

+0

Я может быть недопонимание, но вы ожидаете ваш 'newMove' виртуальный, чтобы спастись? Поскольку виртуальные объекты не сохраняются, и вы пропускаете некоторые вызовы 'this.set' в вашем методе по сравнению с [this] (http://mongoosejs.com/docs/2.7.x/docs/virtuals.html). И что такое 'callback'? Как вы называете 'addMove (...)'? – Tony

+0

@ Тони Да, я ожидал сделать это, как показано в [guide] (http://mongoosejs.com/docs/guide.html) (поиск mad.name.full = 'Breaking Bad';), но, похоже, это не работает. Я просто попробовал то, что вы предложили, и я поменял '' game.newMove = move; '' для '' game.set ('newMove', move); '' и поведение по-прежнему одинаковы. Затем я попробовал сбросить виртуальные все вместе и использовать '' game._field [to] = game._field [from]; game._field [from] = ""; ", но изменение все равно не сохраняется. –

+0

@Tony Callback - это функция, которую я передаю методу базы данных из метода контроллера сокетов и ожидает два параметра: (err, data). Я изменил OP и добавил код, где я вызываю метод базы данных. –

ответ

2

Видимо, mongoose не обнаруживает, что поле было изменено, если вы изменяете массивы напрямую. Для того, чтобы вызвать обнаружение я this.markModified('_field');

Есть некоторые другие методы, чтобы сделать это позже я узнал: Mongoose: assign field of type 'array of Strings'

+0

Когда я увидел вашу схему, я знал. – Tony

Смежные вопросы