2012-06-06 3 views
3

Я пытаюсь сохранить задачу в списке задач с помощью мангуста и MongoDB. Я хочу сохранить его избыточно в коллекции задач и в соответствующем документе списка в виде встроенного документа.mongoose.js: _id встроенного документа

Это прекрасно работает, но одна мелочь: Вложенные документы списка не имеют своих объектов. Но я нуждаюсь в них, чтобы логически связать их с документами в коллекции задач.

Мои Schemas:

var TaskSchema = new Schema({ 
    _id: ObjectId, 
    title: String, 
    list: ObjectId 

}); 

var Task = mongoose.model('task', TaskSchema); 

var ListSchema = new Schema({ 
    _id: ObjectId, 
    title: String, 
    tasks: [Task.schema] 
}); 

var List = mongoose.model('list', ListSchema); 

Мой контроллер/маршрутизатор:

app.post('/lists/:list_id/tasks', function(req, res) { 

     var listId = req.params.list_id; 

     // 1. Save the new task into the tasks-collection. 

     var newTask = new Task(); 
     newTask.title = req.body.title; 
     newTask.list = listId; 

     console.log('TaskId:' + newTask._id); // Returns undefined on the console!!! 

     newTask.save(); // Works fine! 

     // 2. Add the new task to the coresponding list. 

     list.findById(listId, function(err, doc){ 

      doc.tasks.push(newTask); 

      doc.save(); // Saves the new task in the list but WITHOUT its objectId 

      }); 

     res.redirect('/lists/' + listId) 

}); 

Могу ли я использовать мангуст другой способ достичь этого? Или мне нужно сохранить задачу, а затем запросить ее, прежде чем сохранять ее в списке?

Спасибо за совет :-)

ответ

8

я решил его с помощью удивительной особенностью называется populate!

Также dtryon был прав: вам не нужно объявлять объекты _id ObjectIds в своих моделях, они все равно добавляются. И вам нужно вложить этот материал, потому что ваша задача сохраняется несинхронно, поэтому вы должны убедиться, что это работает перед другим.

Вот решение:

Schemas:

var TaskSchema = new Schema({ 
    title: String, 
    list: { type: Schema.ObjectId, ref: 'list' } 

}); 

var Task = mongoose.model('task', TaskSchema); 

var ListSchema = new Schema({ 
    title: String, 
    tasks: [{ type: Schema.ObjectId, ref: 'task' }] 
}); 

var List = mongoose.model('list', ListSchema); 

Контроллер/маршрутизатор:

app.post('/lists/:list_id/tasks', function(req, res) { 

    var listId = req.params.list_id; 

    var newTask = new Task(); 
    newTask.title = req.body.title; 
    newTask.list = listId; 


    // WHEN SAVING, WRAP THE REST OF THE CODE 

    newTask.save(function (err){ 
     if (err) { 
      console.log('error saving new task'); 
      console.log(err); 
     } else { 
      console.log('new task saved successfully'); 

      list.findById(listId), function(err, doc){ 

       doc.tasks.push(newTask); 

       doc.save(function (err){ 
        if (err) { 
        console.log('error adding new task to list'); 
        console.log(err); 
        } else { 

        console.log('new task saved successfully'); 
        res.redirect('/lists/' + listId); 

        } 
       }); 
      }); 
     }); 
    }); 
}); 

Теперь он ссылается правильно и с функцией заселить вы можете получить доступ к записи очень удобно. Работает как charm :-)

1

Я думаю, что это, возможно, придется делать с асинхронным. Возможно, вы не видите ObjectId, потому что вы вызываете list.findByIdпотенциально, прежде чем нажимать newTask. Кроме того, у вас возникнут проблемы с выполнением операции res.redirect за пределами операции async.

Попробуйте это:

app.post('/lists/:list_id/tasks', function(req, res) { 

     var listId = req.params.list_id; 

     // 1. Save the new task into the tasks-collection. 

     var newTask = new Task(); 
     newTask.title = req.body.title; 
     newTask.list = listId; 

     console.log('TaskId:' + newTask._id); // Returns undefined on the console!!! 

     // WHEN SAVING, WRAP THE REST OF THE CODE 
     newTask.save(function (err){ 
      if (err) { 
       console.log(err); 
        // do something 
      } 

      // 2. Add the new task to the coresponding list. 

      list.findById(listId, function(err, doc){ 

       doc.tasks.push(newTask); 

       doc.save(); // Saves the new task in the list but WITHOUT its objectId 

       // REDIRECT AFTER SUCCESS 
       res.redirect('/lists/' + listId) 

      }); 
     }); 
}); 
+0

Я не понимаю, что вы хотите сделать с этим :-(Но он также не работает: по-прежнему нет ObjectId для вложенных документов ... – Sven

+1

Кроме того, я не уверен, вам нужно определить _id на схеме, если вы хотите сгенерировать. Проверьте это: http://stackoverflow.com/questions/6854431/how-do-get-the-objectid-after-i-save-an -объект-в-мангусты –

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