【问题标题】:Population and Subdocuments, What am I doing wrong?人口和子文件,我做错了什么?
【发布时间】:2015-07-15 15:39:13
【问题描述】:

我对 mongoose 的 Population 和 Subdocuments 感到非常困惑,谁能帮我理解它背后的概念?请随时发布示例。

如果我不清楚,请不要生我的气,我是表达和 mongodb 的新手,但我会尽力解释我要完成的工作。

我要做的是创建一个新用户,并创建一个属于这个新用户任务列表。当我保存新用户时,它还会在 tasks: [] 中保存一组任务。所以...我创建了一个用户模式、任务模式、创建视图和用户控制器。

这就是我所拥有的,我现在迷失了。获得要保存的用户名,但任务为空。

我做错了什么?

模型/User.js

var mongoose = require('mongoose'),
    Task = require('./Task'),
    Schema = mongoose.Schema;

var userSchema = new Schema({
    name: {
        type: String,
        unique: true
    },
    tasks: [Task]
});

module.exports = mongoose.model('User', UserSchema);

模型/Task.js

var mongoose = require('mongoose'),
    User = require('./User'),
    Schema = mongoose.Schema;

var TaskSchema = new Schema({
    title : String,
    description : String,
    complete : Boolean,
    userID : {
        type : Schema.ObjectId,
        ref : 'User'
    }
});
module.exports = mongoose.model('Task', TaskSchema);

views/user/create.jade

block content
    form(action='/user/save', method='POST')
        input(type='text', name='title', id='title')
        input(type='text', name='description', id='description')
        input(type='checkbox', name='complete', id='complete')

        button.btn(type='submit') Save

控制器/用户/create.js

var User = require('../../models/User'),
    Task = require('../../models/Task');

// CREATE
exports.get = function(req, res) {
    res.render('user/create', {
        title: 'Create User'
    });
};

exports.post = function(req, res, next) {
    var user = new User({
        name: req.body.name,
        title: req.body.title,
        description: req.body.description,
        complete: req.body.complete
    });

    User.findOne({name:req.body.name}, function(err, existing) {
        if (err) {
            return next(err);
        }
        user.save(function(err) {
            if (err) {
                return next(err);
            }
            res.redirect('/users');
        });
    });
};

控制器/用户/edit.js

var User = require('../../models/User'),
    Task = require('../../models/Task');

// EDIT
exports.get = function(req, res) {
    User.findById(req.params.id, function(err, user) {
        res.render('user/edit', {
            user: user,
            title: 'Edit User'
        });
    });
};

exports.post = function(req, res, next) {
    User.findById(req.params.id, function(err, user) {
        if (err) {
            return next(err);
        }
        user.name = req.body.name || '';
        user.title = req.body.title || '';
        user.description = req.body.description || '';
        user.complete = req.body.complete || '';

        user.save(function(err) {
            if (err) {
                return next(err);
            }
            res.redirect('/users');
        });
    });
};

控制器/路由.js

var create = require('./user/create'),
    edit = require('./user/edit');

exports = module.exports = function(app) {
    // Users
    app.get('/user/create', create.get);
    app.post('/user/save', create.post);
    app.get('/user/edit/:id', edit.get);
    app.post('/user/update/:id', edit.post);
};

【问题讨论】:

  • 看起来上面的代码是正确的我认为这是正确的

标签: javascript node.js express mongoose pug


【解决方案1】:

三件事:

第一

您的架构将 Task 定义为嵌套在 User 中的东西,但您的表单和路由被设计为好像它们是同一个对象。更具体地说,这段代码:

user.name = req.body.name || '';
user.title = req.body.title || '';
user.description = req.body.description || '';
user.complete = req.body.complete || '';

user.save(function(err) {...

只会更改用户名,因为这是您触摸的唯一与您的架构匹配的字段:

var userSchema = new Schema({
    name: {
        type: String,
        unique: true
    },
    tasks: [Task]
});

如果您想为该用户添加新任务,您可以这样做:

user.tasks.push({
    title: req.body.title,
    description: req.body.description,
    complete: req.body.complete
})

user.save(function(err) {...

第二

你的路线有点傻。例如,我希望路由 POST /user/update/:id 仅接受用户属性或任务作为数组。如果我想要为给定用户创建单个任务的路线,我会这样做:POST /user/:id/task,然后我会使用这样的 mongo 查询将任务直接推送到 User.tasks:

// note that incoming data (req.params and req.body) should be validated by your controller, omitted here for brevity
User.update({_id: req.params.id}, {$push: {'tasks': req.body}}, function(err) {...})

第三

在 mongoose 中,Schema(文档结构)和 Model(具有自己的可以实例化的 mongodb 集合的东西)之间存在区别。我不确定您是否打算将 Tasks 定义为自己的模型。您可能想要的是将 Tasks 嵌套在 User.tasks 中,在这种情况下您应该这样做:

var TaskSchema = new Schema({
    title : String,
    description : String,
    complete : Boolean
});

var userSchema = new Schema({
    name: {
        type: String,
        unique: true
    },
    tasks: [TaskSchema]
});

您没有必须在用户中嵌套任务,替代方法是将它们定义为 mongo 中的单独集合并让它们相互引用,就像您在 Task.userID 中所做的那样。但我建议不要将这两种方法混合在一起。

【讨论】:

    猜你喜欢
    • 2020-02-11
    • 2021-09-24
    • 2013-08-10
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 1970-01-01
    相关资源
    最近更新 更多