繁体   English   中英

为什么我的猫鼬一对多人际关系不正确?

[英]Why are my Mongoose One-To-Many Relationships not associating properly?

有谁知道为什么下面的“用户”和“帖子”之间的一对多关系(用户可以有很多帖子)不起作用? 看来我有正确的设置我的猫鼬的关联,但创建一个新的职位时,它不仅是分配一个用户,但用户本身也没有任何职位有关。 我不确定在这里我可能做错了什么。

如果您在下面看到JSON对象,则该对象应具有user值,表示创建帖子的用户。 您将在下面的帖子模型中看到,应该创建一个用户值,但不是。

我究竟做错了什么?

这是创建新帖子后的JSON对象

{
    __v: 0
     _id: "587ee8f5a99b1709b012ce8f"
    createdAt: "2017-01-18T04:03:01.446Z"
    message: "This is my first test post!"
    updatedAt: "2017-01-18T04:03:01.446Z"
}

问题 :尽管在下面的帖子模型中创建了用户字段,但为什么在上面的JSON中缺少用户字段?

这是我的帖子模型:

// Setup dependencies:
var mongoose = require('mongoose');

// Setup a schema:
var PostSchema = new mongoose.Schema (
    {
        message: {
            type: String,
            minlength: 2,
            maxlength: 2000,
            required: true,
            trim: true,
        }, // end message field
        user: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'User'
        },
    },
    {
       timestamps: true,
    }
);

// Instantiate our model and export it:
module.exports = mongoose.model('Post', PostSchema)

这是我的用户模型:

// Setup dependencies:
var mongoose = require('mongoose');

// Setup a schema:
var UserSchema = new mongoose.Schema (
    {
        username: {
            type: String,
            minlength: 2,
            maxlength: 20,
            required: true,
            trim: true,
            unique: true, // username must be unique
            dropDups: true,
            lowercase: true,
            validate: {
                validator: function(username) {
                    var regex = /^[a-z0-9_]+$/i;
                    return regex.test(username);
                },
                message: 'Username may contain only letters, numbers or underscores.',
            },
        }, // end username field
        posts: [{
            type: mongoose.Schema.Types.ObjectId,
            ref: 'Post'
        }],
    },
    {
        timestamps: true,
    });

// Instantiate our model and export it:
module.exports = mongoose.model('User', UserSchema)

这是查询数据库的控制器:

注意 :这是提交表单后运行的方法。

// Grab our Mongoose Models:
var User = require('mongoose').model('User');
var Post = require('mongoose').model('Post');

module.exports = {
    // Creates a new post for logged in user:
    newPost: function(req, res) {
        Post.create(req.body)
            .then(function(newPost) {
                return res.json(newPost);
            })
            .catch(function(err) {
                return res.json(err);
            })

    }
};

有谁知道我的关联设置不正确,这就是为什么我没有在他们各自的字段中显示任何实际的帖子或用户的原因?

似乎是我的服务器端控制器正确触发了,因为帖子实际上是创建的。 但是协会本身并没有联系在一起,我不确定我在做什么错。

我在下面添加一个简单的答案,以继续上面的示例。 基本上,@ cdbajorin是正确的,我一直在思考正在进行一些自动化,并且没有适当地遵循正确的猫鼬命令来实现我想要的结果。

我的问题的解决方案如下:

  1. 在用户模式,更新UserSchema posts属性是一个空数组,而不是mongoose.Schema.Types.ObjectID ,因为对象ID这里没有存储无论如何,我误解是如何工作的。

编码:

posts: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Post'
}],

相反,应该简单地写成:

posts: [],
  1. 服务器控制器中的newPost方法应作如下修改(有关说明,请参见内联注释):

     newPost: function(req, res) { // creates new post: Post.create(req.body) .then(function(newPost) { // look up current user based on session ID: // note: session setup not shown in this example. User.findById(req.session.userID) .then(function(user) { // push new post into users.posts array from model setup**: user.posts.push(newPost); user.save(); return res.json(newPost); }) }) .catch(function(err) { return res.json(err); }) 

这确实解决了生成新帖子的问题,然后将其推送到用户的posts数组中(来自UsersSchema )。

尽管最初的帖子中的问题已解决,但人们可能会质疑这是否是数据库管理的最佳用途。 如本例所示,在用户内部存储帖子会占用大量空间,因为用户和帖子开始累加。

该帖子最终在数据库中重复两次:首先,作为本身在posts集合中的文档,其次,作为UserSchema内的posts数组中的UserSchema

更好的解决方案是将帖子保留为posts集合中的唯一文档,但是将会话信息中的userID添加到其中。 然后,如果由于某种原因需要所有用户的帖子,则基于userID查询Posts集合将返回为其分配了该userID的所有帖子。 然后,数据库中仅存在一个帖子副本,而不是两个。

**附加说明:修改现有文档的另一种方法是使用实​​例方法,将实际方法插入用户模型(Schema)文件中,并在需要时调用:

例如,在上面的UserSchema模型中的module.exports行之前插入以下代码,可以在需要时方便地访问此功能:

UserSchema.methods.addPost = function(post) {
    this.posts.push(post);
    this.save();
    return true;
};

要从服务器控制器中调用此实例方法,我们可以按以下方式重新编写控制器:

User.findById(req.session.userID)
    .then(function(user) {
     // call our instance method above:
        user.addPost(newPost);
        return res.json(newPost);
     });

该帖子将通过实例方法推入并保存,该实例方法已内置在实例对象本身中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM