Как получить список всех сообщений конкретного пользователя в Express / Mon go? - PullRequest
0 голосов
/ 05 февраля 2020

У меня есть модель «Пользователь и сообщения», и есть лента пользователя, в которой будут показаны все сообщения, отправленные пользователем.

Пользователь. js

const mongoose = require("mongoose")
const bcrypt = require("bcrypt")
const Schema = mongoose.Schema

const userSchema = new Schema({
    username: { type: String, required: true },
    email: { type: String, required: true },
    password: { type: String, required: true },
}, { timestamps: true })


userSchema.pre("save", function (next) {
    if (this.password) {
        const salt = bcrypt.genSaltSync(10)
        this.password = bcrypt.hashSync(this.password, salt)
    }
    next()
})

userSchema.methods.confirmPassword = function (password) {
    return bcrypt.compareSync(password, this.password)
}


const User = mongoose.model("User", userSchema)

module.exports = User

Пост. js

const mongoose = require("mongoose");
const Schema = mongoose.Schema;
var URLSlug = require("mongoose-slug-generator");

mongoose.plugin(URLSlug);

const postSchema = new Schema({
  postTitle: { type: String, required: true },
  postDescription: { type: String, required: true },
  userId: { type: Schema.Types.ObjectId, ref: "User" },
  slug: { type: String, slug: "title" }
}, { timestamps: true }
)

postSchema.pre("save", function (next) {
  this.slug = this.postTitle.split(" ").join("-");
  next();
});

const Post = mongoose.model("post", postSchema);

module.exports = post;

Маршруты выглядят как это:

сообщений. js

router.post("/new", auth.verifyToken, postsController.newposts)
router.get("/list", postsController.listpostss)
router.get("/:id", postsController.findposts)
router.put("/:id/edit", postsController.updateposts)
router.delete("/:id/delete", postsController.deleteposts)

пользователей. js

router.post("/register", usersController.registerUser)
router.post("/login", usersController.loginUser)
router.get("/me", auth.verifyToken, usersController.identifyUser)
router.get("/list", usersController.listUsers)
router.get("/:id", usersController.getUser)
router.put("/:id/edit", usersController.updateUser)
router.delete("/:id/delete", usersController.deleteUser)

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

1 Ответ

1 голос
/ 05 февраля 2020

Поскольку у вас нет ссылок от пользователя к записи, вы можете использовать виртуальное население для этого:

Сначала обновите схему пользователя следующим образом: (обратите внимание, что я добавил toJSON: { virtuals: true } и определено userSchema.virtual)

const userSchema = new Schema(
  {
    username: { type: String, required: true },
    email: { type: String, required: true },
    password: { type: String, required: true }
  },
  { timestamps: true, toJSON: { virtuals: true } }
);

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

Теперь вы можете заполнять сообщения от пользователя как обычное население:

router.get("/user-posts", async (req, res) => {
  try {
    const userId = req.user.id; //change this to logged -in user id
    const result = await User.findById(userId).populate("posts");
    res.send(result);
  } catch (err) {
    console.log(err);
    res.status(500).send("Something went wrong, check logs");
  }
});

Допустим, у нас есть этот существующий пользователь:

{
    "_id": "5e3a885ec511414a3c37a78c",
    "username": "metalHeadDev",
    "email": "metal@head.dev",
    "password": "123123",
    "createdAt": "2020-02-05T09:18:22.948Z",
    "updatedAt": "2020-02-05T09:18:22.948Z",
    "__v": 0,
    "id": "5e3a885ec511414a3c37a78c"
}

И эти 2 сообщения от этого пользователя:

{
    "_id": "5e3a88e2c511414a3c37a78d",
    "postTitle": "title1",
    "postDescription": "description1",
    "userId": "5e3a885ec511414a3c37a78c",
    "slug": "title1",
    "createdAt": "2020-02-05T09:20:34.529Z",
    "updatedAt": "2020-02-05T09:20:34.529Z",
    "__v": 0
}

{
    "_id": "5e3a88f1c511414a3c37a78e",
    "postTitle": "title2",
    "postDescription": "description2",
    "userId": "5e3a885ec511414a3c37a78c",
    "slug": "title2",
    "createdAt": "2020-02-05T09:20:49.754Z",
    "updatedAt": "2020-02-05T09:20:49.754Z",
    "__v": 0
}

Результат будет таким:

{
    "_id": "5e3a885ec511414a3c37a78c",
    "username": "metalHeadDev",
    "email": "metal@head.dev",
    "password": "123123",
    "createdAt": "2020-02-05T09:18:22.948Z",
    "updatedAt": "2020-02-05T09:18:22.948Z",
    "__v": 0,
    "posts": [
        {
            "_id": "5e3a88e2c511414a3c37a78d",
            "postTitle": "title1",
            "postDescription": "description1",
            "userId": "5e3a885ec511414a3c37a78c",
            "slug": "title1",
            "createdAt": "2020-02-05T09:20:34.529Z",
            "updatedAt": "2020-02-05T09:20:34.529Z",
            "__v": 0
        },
        {
            "_id": "5e3a88f1c511414a3c37a78e",
            "postTitle": "title2",
            "postDescription": "description2",
            "userId": "5e3a885ec511414a3c37a78c",
            "slug": "title2",
            "createdAt": "2020-02-05T09:20:49.754Z",
            "updatedAt": "2020-02-05T09:20:49.754Z",
            "__v": 0
        }
    ],
    "id": "5e3a885ec511414a3c37a78c"
}

В качестве альтернативы секунд мы можем использовать структуру агрегации mongodb. Это решение не требует никаких изменений в схемах и может быть предпочтительным.

const ObjectId = require("mongoose").Types.ObjectId;

router.get("/user-posts", async (req, res) => {
  try {
    const userId = req.user.id; //change this to logged -in user id
    const result = await User.aggregate([
      {
        $match: {
          _id: ObjectId(userId)
        }
      },
      {
        $lookup: {
          from: "posts",        //must be collection name for posts
          localField: "_id",
          foreignField: "userId",
          as: "posts"
        }
      }
    ]);

    if (result.length > 0) {
      res.send(result[0]);
    } else {
      res.status(404).send("User not found");
    }
  } catch (err) {
    console.log(err);
    res.status(500).send("Something went wrong, check logs");
  }
});

Это даст тот же результат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...