Пн goose & Express: Как правильно удалять, создавать и хранить данные, которые являются справочными - PullRequest
1 голос
/ 17 января 2020

Проблема first , с которой я столкнулся, заключается в том, что всякий раз, когда я пытаюсь удалить комментарий, я также пытаюсь найти индекс этого конкретного c комментария внутри post.comments как как и внутри user.comments , он последовательно возвращает -1, причина, по которой я пытаюсь его найти, заключается в том, что я могу склеить его из массива комментариев, который есть у пользователя и поста. Проблема second , с которой я столкнулся, заключается в том, что всякий раз, когда я создаю комментарий, я пытаюсь сохранить его в массиве комментариев, который есть у пользователя и записи, но он сохраняет его только в виде строки, хотя я думаю, что это предполагается быть сохраненным как объект правильно ?, так что я могу получить к нему доступ позже, заполнив?

Я боролся в течение нескольких дней, будучи очень расстроенным, почему он не работает. Пожалуйста, помогите мне!

Ниже будут мои два маршрута для удаления и создания комментариев, и мои схемы, Спасибо за помощь!

Создание комментариев

// @route    POST api/posts/comment/:id
// @desc     Comment on a post
// @access   Private
router.post(
  '/comment/:id',
  [
    auth,
    [
      check('text', 'Text is required')
        .not()
        .isEmpty()
    ]
  ],
  async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }

    try {
      const post = await Post.findById(req.params.id);
      const user = await User.findById(req.user.id)
      const newComment = {
        text: req.body.text,
        post: post._id,
        user: req.user.id
      };
      const comment = new Comment(newComment);
      post.comments.unshift(comment._id);
      user.comments.unshift(comment._id)
      console.log(user.comments);
      console.log(post.comments);
      console.log(comment)
      await post.save();
      await comment.save();
      await user.save();
      res.json(comment);
    } catch (err) {
      console.error(err.message);
      res.status(500).send('Server Error');
    }
  }
);

Удаление комментариев

// @route    DELETE api/posts/comment/:id/:comment_id
// @desc     Delete comment
// @access   Private
router.delete('/comment/:id/:comment_id', auth, async (req, res) => {
  try {
    const post = await Post.findById(req.params.id);
    const user = await User.findById(req.user.id);

    // Pull out comment by finding it through its id
    const comment = await Comment.findById(req.params.comment_id);

    // Make sure comment exists
    if (!comment) {
      return res.status(404).json({ msg: 'Post do not have this comment' });
    }

    // Check user
    if (comment.user.toString() !== req.user.id) {
      return res.status(401).json({ msg: 'User not authorized' });
    }

      // Get The value to be removed
      const postCommentIndex = post.comments.findIndex(postComment => postComment === comment._id);


      const userCommentIndex = user.comments.findIndex(userComment => userComment === comment._id);

      console.log(`This is the post comment index ${postCommentIndex}`);
      console.log(`This is the user comment index ${userCommentIndex}`);

      post.comments.splice(postCommentIndex, 1);
      user.comments.splice(userCommentIndex, 1);

    // save user and post
    await post.save();
    await user.save();
    await comment.remove();

    // resend the comments that belongs to that post
    res.json(post.comments);
  } catch (err) {
    console.error(err.message);
    res.status(500).send('Server Error');
  }
});

Схемы:

const mongoose = require('mongoose');

const UserSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true
  },
  email: {
    type: String,
    required: true,
    unique: true
  },
  password: {
    type: String,
    required: true
  },
  avatar: {
    type: String
  },
  posts: [{type: mongoose.Schema.Types.ObjectId, ref: "Post"}],
  comments: [{type: mongoose.Schema.Types.ObjectId, ref: "Comment"}],
  date: {
    type: Date,
    default: Date.now
  }
});

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

const PostSchema = new Schema({
  user: {
    type: Schema.Types.ObjectId,
    ref: 'User'
  },
  text: {
    type: String,
    required: true
  },
  likes: [
    {
      user: {
        type: Schema.Types.ObjectId,
        ref: 'User'
      }
    }
  ],
  dislikes: [
    {
        user: {
            type: Schema.Types.ObjectId,
            ref: "User"
        }
    }
  ],
  comments: [{type: Schema.Types.ObjectId, ref: "Comment"}],
  date: {
    type: Date,
    default: Date.now
  }
});

module.exports = mongoose.model('Post', PostSchema);
const mongoose = require("mongoose")
const Schema = mongoose.Schema;


const CommentSchema = new Schema({
        user: {
            type: Schema.Types.ObjectId,
            ref: 'User'
        },
        post: {
            type: Schema.Types.ObjectId,
            ref: "Post"
        },
        text: {
            type: String,
            required: true
        },
        date: {
            type: Date,
            default: Date.now
        }
})

module.exports = mongoose.model("Comment", CommentSchema);

Ответы [ 2 ]

2 голосов
/ 17 января 2020

Я думаю, что вам нужно перестроить свои схемы более простым способом, слишком много ссылок между моделями, и это вызывает проблемы, например, у вас есть доступ на 5 дБ, когда вы хотите создать комментарий, и доступ на 6 дБ, когда Вы хотите удалить комментарий.

Я бы создал такую ​​схему пользователя, удалив сообщения и ссылки на комментарии, но позже, когда мы захотим получить доступ к сообщениям от пользователей, я настрою виртуальное заполнение.

const UserSchema = new Schema(
  {
    name: {
      type: String,
      required: true
    },
    email: {
      type: String,
      required: true,
      unique: true
    },
    password: {
      type: String,
      required: true
    },
    avatar: {
      type: String
    },
    date: {
      type: Date,
      default: Date.now
    }
  },
  {
    toJSON: { virtuals: true }
  }
);

UserSchema.virtual("posts", {
  ref: "Post",
  localField: "_id",
  foreignField: "user"
});

И в схеме сообщений я удалил ссылки на комментарии. (Для простоты я удалил поля «Нравится» и «Не нравится».)

const PostSchema = new Schema(
  {
    user: {
      type: Schema.Types.ObjectId,
      ref: "User"
    },
    text: {
      type: String,
      required: true
    },
    date: {
      type: Date,
      default: Date.now
    }
  },
  {
    toJSON: { virtuals: true }
  }
);

PostSchema.virtual("comments", {
  ref: "Comment",
  localField: "_id",
  foreignField: "post"
});

Схема комментариев может оставаться без изменений.

Теперь, чтобы добавить комментарий к сообщению, нам нужен только 2 дБ доступа, один для проверки, существует ли пост, и один для создания поста.

router.post(
  "/comment/:id",
  [
    auth,
    [
      check("text", "Text is required")
        .not()
        .isEmpty()
    ]
  ],
  async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }

    try {
      const post = await Post.findById(req.params.id);
      if (!post) {
        return res.status(404).json({ msg: "Post not found" });
      }

      let comment = new Comment({
        text: req.body.text,
        post: req.params.id,
        user: req.user.id
      });

      comment = await comment.save();

      res.json(comment);
    } catch (err) {
      console.error(err.message);
      res.status(500).send("Server Error");
    }
  }
);

Допустим, у нас есть 2 пользователя:

{
    "_id" : ObjectId("5e216d74e7138b638cac040d"),
    "name" : "user1"
}
{
    "_id" : ObjectId("5e217192d204a26834d013e8"),
    "name" : "user2"
}

Пользователь1 с _id:"5e216d74e7138b638cac040d" имеет этот пост.

{
    "_id": "5e2170e7d204a26834d013e6",
    "user": "5e216d74e7138b638cac040d",
    "text": "Post 1",
    "date": "2020-01-17T08:31:35.699Z",
    "__v": 0,
    "id": "5e2170e7d204a26834d013e6"
}

Допустим, user2 с _id:"5e217192d204a26834d013e8" прокомментировал этот пост два раза так:

{
    "_id" : ObjectId("5e2172a4957c02689c9840d6"),
    "text" : "User2 commented on user1 post1",
    "post" : ObjectId("5e2170e7d204a26834d013e6"),
    "user" : ObjectId("5e217192d204a26834d013e8"),
    "date" : ISODate("2020-01-17T11:39:00.396+03:00"),
    "__v" : 0
},
{
    "_id": "5e21730d468bbb7ce8060ace",
    "text": "User2 commented again on user1 post1",
    "post": "5e2170e7d204a26834d013e6",
    "user": "5e217192d204a26834d013e8",
    "date": "2020-01-17T08:40:45.997Z",
    "__v": 0
}

Чтобы удалить комментарий, мы можем использовать следующий маршрут, как вы видите, мы уменьшили Доступ к базе данных с 6 до 3, а код короче и чище.

router.delete("/comment/:id/:comment_id", auth, async (req, res) => {
  try {
    const comment = await Comment.findById(req.params.comment_id);

    if (!comment) {
      return res.status(404).json({ msg: "Post do not have this comment" });
    }

    if (comment.user.toString() !== req.user.id) {
      return res.status(401).json({ msg: "User not authorized" });
    }

    await comment.remove();

    // resend the comments that belongs to that post
    const postComments = await Comment.find({ post: req.params.id });
    res.json(postComments);
  } catch (err) {
    console.error(err.message);
    res.status(500).send("Server Error");
  }
});

Теперь вы можете спросить, как вы будете получать доступ к сообщениям от пользователя? Поскольку мы настраиваем виртуальное заполнение в нашей пользовательской схеме, мы можем заполнять сообщения следующим образом:

router.get("/users/:id/posts", async (req, res) => {
  const result = await User.findById(req.params.id).populate("posts");

  res.send(result);
});
0 голосов
/ 17 января 2020

Вы можете попробовать этот фрагмент кода:

Comment.deleteOne({
_id: comment.id
}, function (err) {
if (err) {
  console.log(err);
  return res.send(err.message);
}
res.send('success');
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...