Я пытался использовать Populate в mon goose, но это не сработало - PullRequest
0 голосов
/ 26 марта 2020

Привет всем, у меня проблема, может быть, вы можете мне помочь. Таким образом, в основном я создал две коллекции в пн goose, одну для сведений о пользователе при регистрации или входе в систему и другую для рецепта, который они публикуют. Я также хотите сохранить каждый рецепт пользовательского поста в коллекции пользователей (например, свойство populate для mon goose). Например, если пользователь1 опубликовал рецепт1, его следует сохранить в коллекции рецептов, а также в данных пользователя, которые его опубликовали. Я попытался использовать Заполнить метод для этого, как показано в коде ниже, но когда я публикую какой-либо рецепт, он хранится только в коллекции рецептов, а ключ "posts" в коллекции пользователей всегда пуст. Я хочу также сохранить рецепт в ключе «записей» коллекции пользователей. Пожалуйста, объясните мне, как это сделать.

require('dotenv').config()
const express = require("express");
const bodyParser = require("body-parser");
const ejs = require("ejs");
const requestObj = require("request");
const https = require("https");
const multer = require("multer");
const path = require("path");
const mongoose = require('mongoose');
const session = require('express-session');
const passport = require("passport");
const passportLocalMongoose = require("passport-local-mongoose");
const findOrCreate = require('mongoose-findorcreate');
const app = express();
const GoogleStrategy = require('passport-google-oauth20').Strategy;


app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({
  extended: true
}));
app.use(express.static("public"));

app.use(session({
  secret: "This is my secret",
  resave: false,
  saveUninitialized: false
}));

app.use(passport.initialize());
app.use(passport.session());

// Mongoose connection
mongoose.connect("mongodb://localhost:27017/recipeUsers", {
  useNewUrlParser: true,
  useUnifiedTopology: true
});
mongoose.set('useCreateIndex', true);

//mongoose schema



const userSchema = new mongoose.Schema({
  username: String,
  password: String,
  googleId: String,
  name: String,
  posts: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Recipe'
  }]
});

const recipeSchema = new mongoose.Schema({
  genre: String,
  name: String,
  description: String,
  ingredients: [{
    type: String
  }],
  method: [{
    type: String
  }],
  imageName: String,
  author: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'User'
  }
});

userSchema.plugin(passportLocalMongoose);
userSchema.plugin(findOrCreate);

// model
const Recipe = mongoose.model("Recipe", recipeSchema);
const User = mongoose.model("User", userSchema);

module.exports = {
  User,
  Recipe,
}

passport.use(User.createStrategy());

passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  User.findById(id, function(err, user) {
    done(err, user);
  });
});

passport.use(new GoogleStrategy({
    clientID: process.env.CLIENT_ID,
    clientSecret: process.env.CLIENT_SECRET,
    callbackURL: "http://localhost:5000/auth/google/index",
    userProfileURL: "https://www.googleapis.com/oauth2/v3/userinfo"
  },
  function(accessToken, refreshToken, profile, cb) {
    // console.log(profile);
    User.findOrCreate({
      googleId: profile.id,
      name: profile.displayName
    }, function(err, user) {
      return cb(err, user);
    });
  }
));


var storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, "public/img/uploads")
  },
  filename: (req, file, cb) => {
    cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
  }
});

var upload = multer({
  storage: storage,
  limits: {
    fileSize: 5 * 1024 * 1024
  }
});


app.use((req, res, next) => {
  res.locals.isAuthenticated = req.isAuthenticated();
  if (req.isAuthenticated()) {
    currentUser = req.user.name;
  }
  next();
});

app.get("/", function(req, res) {
  res.render("index");
});

app.get("/index", (req, res) => {
  res.render('index');
});

app.get("/about", function(req, res) {
  res.render("about");
});

app.route("/search")
  .get(function(req, res) {
    res.render("search");
  })
  .post(function(req, res) {
    const searchRecipe = req.body.recipeName;
    Recipe.findOne({
      name: searchRecipe
    }, (err, foundRecipe) => {
      if (err) {
        res.send(err);
      } else {
        if (foundRecipe) {
          res.render("recipe", {
            dishName: foundRecipe.name,
            descrip: foundRecipe.description,
            genre: foundRecipe.genre,
            ingredients: foundRecipe.ingredients,
            steps: foundRecipe.method,
            author: foundRecipe.author,
            dishImage: foundRecipe.imageName
          });
        } else {
          res.redirect("/Failure");
        }
      }
    });
  });

app.get("/Failure", function(req, res) {
  res.render("Failure");
});


app.route("/post")
  .get(function(req, res) {
    if (req.isAuthenticated()) {
      res.render("post", {
        message: ""
      });
    } else {
      res.redirect("/login");
    }

  })
  .post(upload.single('dishImage'), function(req, res, next) {
    const dishType = req.body.recipeGenre;
    const description = req.body.description;
    const dishName = req.body.dishName;
    const ingredient = req.body.ingredients;
    const step = req.body.steps;
    // const authorName = req.body.author;
    // const url = "https://polar-oasis-10822.herokuapp.com/recipes";
    const file = req.file;
    if (!file) {
      const error = new Error("Please upload a image");
      error.httpStatusCode = 400;
      return next(error);
    }
    // console.log(req.user);
    const dish = new Recipe({
      genre: dishType,
      name: dishName,
      description: description,
      ingredients: ingredient,
      method: step,
      imageName: file.filename,
    });
    dish.save((err) => {
      if (err) {
        res.send(err);
      } else {
        User.findOne({
            _id: req.user._id
          })
          .populate('posts').exec((err, posts) => {
            console.log("Populated User " + posts);
          })
        res.render("post", {
          message: "Your Recipe is successfully posted."
        });
      }
    });
  });


app.get("/menu", function(req, res) {
  res.render("menu");
});


app.get('/auth/google',
  passport.authenticate('google', {
    scope: ["profile"]
  })
);

app.get('/auth/google/index', passport.authenticate('google', {
  failureRedirect: '/login'
}), function(req, res) {
  // Successful authentication, redirect home.
  res.redirect('/');
});

app.get("/logout", (req, res) => {
  req.logout();
  res.redirect('/');
});


app.route("/signup")
  .get((req, res) => {
    res.render("signup");
  })
  .post((req, res) => {
    User.register({
      username: req.body.username,
      name: req.body.name,
    }, req.body.password, (err, user) => {
      if (err) {
        console.log(err);
        res.redirect("/signup");
      } else {
        passport.authenticate("local")(req, res, () => {
          res.redirect('/');
        });
      }
    });
  })

app.route("/login")
  .get((req, res) => {
    res.render("login");
  })
  .post((req, res) => {
    const user = new User({
      username: req.body.username,
      password: req.body.password
    });
    req.login(user, (err) => {
      if (err) {
        console.log(err);
      } else {
        passport.authenticate("local")(req, res, () => {
          res.redirect("/");
        });
      }
    });
  })

app.listen(process.env.PORT || 5000, function() {
  console.log("server is running on port 5000");
});

1 Ответ

0 голосов
/ 26 марта 2020

Я полагаю, что ваша проблема здесь:

    dish.save((err) => {
      if (err) {
        res.send(err);
      } else {
        User.findOne({
            _id: req.user._id
          })
          .populate('posts').exec((err, posts) => {
            console.log("Populated User " + posts);
          })
        res.render("post", {
          message: "Your Recipe is successfully posted."
        });
      }
    });
  });

Вы используете populate как функцию, которая изменяет элементы набора данных, но это просто прием для печати результатов из другой коллекции, в корнях , они разные; если вы хотите, чтобы они были в одном документе, вы должны использовать вложенные документы. populate не меняет пути к документам.

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

app
  .route("/post")
  .get(function(req, res) {
    if (req.isAuthenticated()) {
      res.render("post", {
        message: ""
      });
    } else {
      res.redirect("/login");
    }
  })
  .post(upload.single("dishImage"), function(req, res, next) {
    const dishType = req.body.recipeGenre;
    const description = req.body.description;
    const dishName = req.body.dishName;
    const ingredient = req.body.ingredients;
    const step = req.body.steps;

    const username = req.body.author; //make sure this information is passed to req.body
    // const url = "https://polar-oasis-10822.herokuapp.com/recipes";
    const file = req.file;
    if (!file) {
      const error = new Error("Please upload a image");
      error.httpStatusCode = 400;
      return next(error);
    }
    // console.log(req.user);
    const dish = new Recipe({
      genre: dishType,
      name: dishName,
      description: description,
      ingredients: ingredient,
      method: step,
      imageName: file.filename
    });
    dish.save(err => {
      if (err) {
        res.send(err);
      } else {
        User.findOne({
          _id: req.user._id
        }).then(user => {//I have changed just here! I have eliminated the populate call
          user.posts.push(dish._id);
          user.save().then(() => {
            console.log("okay");
          });
        });

        res.render("post", {
          message: "Your Recipe is successfully posted."
        });
      }
    });
  });

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

Ссылки

https://mongoosejs.com/docs/populate.html#refs -в-дети

...