Borislav Stefanov
Borislav Stefanov

Reputation: 731

Node.js Mongoose - model in model update

I have 1 Model for blogPosts:

const blogSchema= new mongoose.Schema({
  userId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "User",
  },
  name: {
    type: String,
    required: true,
    max: 50,
    min: 6,
  },
  description: {
    type: String,
    required: true,
    max: 1024,
    min: 25,
  },
  date: {
    type: Date,
    default: Date.now,
  },
  comment: [commentSchema],
});

The important part here is the last field comment. For it I have another schema:

    const commentSchema = new mongoose.Schema({
      date: {
        type: Date,
        default: Date.now,
      },
      comment: {
        type: String,
        max: 1024,
        min: 5,
      },
      userId: {
        type: mongoose.Schema.Types.ObjectId,
        ref: "User",
      },
    });

Normally when post is created, then the comments can be added. In a separate file User.js I have model for User:

const userSchema = new mongoose.Schema({
  name: {
    type: String,
    unique: true,
    required: true,
    max: 255,
    min: 6,
  },
  email: {
    type: String,
    unique: true,
    required: true,
  },

  password: {
    type: String,
    required: true,
    min: 6,
  },
  date: {
    type: Date,
    default: Date.now,
  },
});

How I can connect these to work together. I have endpoint where all posts are visible (no matter which user provided them). I want 1 user to be able to comment post on another user and his name to appear under it.

So any ideas how I can create:

  1. Endpoint which will store comments in blogSchema's comment field
  2. User will be recorded in commentSchema

Upvotes: 0

Views: 154

Answers (2)

Borislav Stefanov
Borislav Stefanov

Reputation: 731

The way I did it:

Separated Comment model in another file:

  const mongoose = require("mongoose");
    
    const commentSchema = new mongoose.Schema({
      date: {
        type: Date,
        default: Date.now,
      },
      comment: {
        type: String,
        max: 1024,
        min: 5,
      },
      userId: {
        type: mongoose.Schema.Types.ObjectId,
        ref: "User",
      },
    });
    
    module.exports = mongoose.model("Comment", commentSchema);

Change comment field as Mohit Gupta suggested in his answer:

const mongoose = require("mongoose");

const blogSchema = new mongoose.Schema({
  //OTHER FIELDS ARE HERE.....
  comment: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "Comment",
    },
  ],
});

module.exports = mongoose.model("Blog", blogSchema);

Then I made the route like this:

//COMMENT
router.post("/comment/:post", verify, async (req, res) => {

  const { comment } = req.body;
  if (!comment) {
    return res
      .status(422)
      .send({ error: "Must provide comment with at least 5 symbols" });
  }

  try {
    const newComment = new Comment({ comment, userId: req.user._id });
    await newComment.save();
    const update = {
      $push: {
        comment: newComment,
      },
    };
    const post= await Blog.findOneAndUpdate(
      { _id: req.params.post },
      update
    );

    res.send(post);
  } catch (err) {
    res.status(422).send({ error: err.message });
  }
});

Upvotes: 1

Mohit Gupta
Mohit Gupta

Reputation: 378

For blogPosts model you need to store the comments array as a reference to the comment, using type object id and ref:"comment"

comment: [{
type: mongoose.Schema.Types.ObjectId,
ref: "commentSchema",
}]

Now when a comment is added to a post,add the comment document id to blogpost->comment array. To fetch the comments on a blogpost, use aggregation or populate the comments related to the blogpost.

Upvotes: 1

Related Questions