Automattic / mongoose

MongoDB object modeling designed to work in an asynchronous environment.
https://mongoosejs.com
MIT License
26.87k stars 3.83k forks source link

I can't store the whole object when i References #10483

Closed SohaibArbiBakcha closed 3 years ago

SohaibArbiBakcha commented 3 years ago

my user Schema

const userSchema = new mongoose.Schema({
  name: {
    type: String,
    trim: true,
    required: true,
  },
  email: {
    type: String,
    trim: true,
    required: true,
  },
  hashed_password: {
    type: String,
    required: true,
  },
  salt: String,
  created: {
    type: Date,
    default: Date.now,
  },
  updated: Date,
});

My post Schema

const mongoose = require("mongoose");
const { ObjectId } = mongoose.Schema;
const User = require("./user");

const postSchema = new mongoose.Schema({
  title: {
    type: String,
    required: true,
  },
  body: {
    type: String,
    required: true,
  },
  photo: {
    data: Buffer,
    contentType: String,
  },
  postedBy: {
    type: ObjectId,
    ref: User,
  },
  created: {
    type: Date,
    default: Date.now,
  },
});

find user by id method

exports.userById = (req, res, next, id) => {
  User.findById(id).exec((err, user) => {
    if (err || !user) {
      return res.status(400).json({ error: "User not found" });
    }

    req.profile = user; // adds profile obejcts to the request
    next();
  });
};

post method

exports.createPost = (req, res, next) => {
  let form = formidable.IncomingForm();
  form.keepExtensions = true;
  form.parse(req, (err, fields, files) => {
    if (err) {
      return res.status(400).json({
        error: "photo could not be uploaded",
      });
    }

    let post = new Post(fields);
    post.postedBy = req.profile;
    if (files.photo) {
      post.photo.data = fs.readFileSync(files.photo.path);
      post.photo.contentType = flies.photo.type;
    }

    post.save((err, result) => {
      if (err) {
        res.status(400).json({ error: err });
      }

      res.json(result);
    });
  });
};

my route

router.post(
  "/post/new/:userId",
  requireSignin,
  createPost,
  createPostValidator
);

// any routes containing userId
router.param("userId", userById);

result i recive when trying to create a post by a user

{
    "_id": "60f98d00fae7d62ef42ba351",
    "title": "admin talkf",
    "body": "Hello debug fase",
    "created": "2021-07-22T15:21:36.102Z",
    "postedBy": "60f48a6d36a1eb15b8082105",
    "__v": 0
}
Kamikadze4GAME commented 3 years ago

Hello @SohaibArbiBakcha

I'm not 100% sure, but it looks like that this is not mongoose's issue.

This block if (files.photo) {...} does not execute. This occurs because files.photo is falsy.

So you should check:

  1. HTML form (enctype, file field etc)
  2. Express configs and middlewares
  3. requireSignin middleware
bhuynhdev commented 3 years ago

Hmm. Since you are not showing what is your expected output, I cannot see what is the problem here. The reference feature seems to be working as intended (Although I remember that it is mongoose.Schema.Types.ObjectId, not mongoose.Schema.ObjectId). Anyhow, a reference field is for storing the IDs of the related document(s). To get the entire User Document, you will need to use Query population

SohaibArbiBakcha commented 3 years ago

@Kamikadze4GAME @baohuynhlam

its an API when i use populate method i got the whole user objects they are no problem

thank a lot for your answers

exports.getPosts = (req, res) => { Post.find() .populate("postedBy", "_id name") .select("title body") .then((posts) => { res.status(200).json({ posts }); }) .catch((error) => console.log(error)); };