привязка заказов к продуктам

#node.js #mongoose

#node.js #мангуст

Вопрос:

У меня возникла проблема при попытке связать конкретный заказ с конкретным продуктом. Я новичок в node.js , я хочу добавить продукт (быть связанным и заполненным заказом) и быть перенаправленным на страницу, на которой показаны все заказы продуктов, которые я создал

создал схему продукта и заказа (не слишком уверен в другой схеме)…

Это моя модель продукта

 var mongoose= require("mongoose");
var productSchema = new mongoose.Schema({
    name:String,
    brand:String,
    price: Number, 
    image: String,
    description:String,
    featured: Boolean,

 });

module.exports= mongoose.model("Product", productSchema);
  

Это модель заказа:

 var mongoose = require("mongoose");
var orderSchema= new mongoose.Schema({

_id: mongoose.Schema.Types.ObjectId,
   products:[
        {
        type: mongoose.Schema.Types.ObjectId,
        ref:"Product", required:true
        }
    ]
,
quantity :{type:Number, default:1}
});
module.exports=mongoose.model("Order",orderSchema);
  

Я хочу, чтобы эти модели были связаны вместе с помощью mongoose метода, были заполнены, а затем, например, отображались на маршруте (« /order ). Я новичок в программировании, и поэтому я был бы признателен за самый простой ответ.

Комментарии:

1. Итак, вы хотите, чтобы в вашей модели заказа были сведения о продукте, я прав?

2. да, пожалуйста, таково намерение

3. Итак, что вы получаете сейчас в своем маршруте для заказов

Ответ №1:

Вот небольшой рабочий пример использования Express.Js , в этом примере я создал 3 модели :

 // Models
const productSchema = new mongoose.Schema({
    name:String
 });

var orderSchema= new mongoose.Schema({
  products:[productSchema]
});

const clientSchema = new mongoose.Schema({
  name: String,
  order: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Order'
  }
})
const Product = mongoose.model('Product', productSchema);
const Client = mongoose.model('Client', clientSchema);
const Order = mongoose.model('Order', orderSchema);
  

Я orderSchema буду встраивать продукты, заказанные моими клиентами, я решил хранить продукты в виде вложенных документов, потому что у меня их будет немного, вы также можете выбрать хранение ссылок вместо этого.
Примечание: я ссылаюсь только на один заказ для каждого клиента, вы можете выбрать иначе и внести поле заказа в clientSchema in an array ( order: [{ /* type...*/}] ) В моем контроллере У меня есть 2 метода: один для создания заказа, а другой для добавления продукта в заказ.

 // Controller
const createOrder = (userId, productId) => {
  Product.findOne({_id: productId}) // find a product
    .exec()
    .then(product => new Order({products: [product]}).save()) // save the products into the order
    .then(order => Client.findOneAndUpdate({_id: userId}, {$set: {order: order}}).exec())// update the client document with the new order
    .then(client => res.json(client)); // respond with json
    // .catch(err => console.log(err))
}
const addToOrder = (userId, productId) => {
  return Product.findOne({_id: productId}) // find the product
    .exec()
    .then(product => {
      return Client.findOne({_id: userId})//find the client
        .populate({ path: 'order', populate: { path: 'order.products' } })
        .exec() //populate in order to access client.order.products
        .then(client => {
          client.order.products.push(product);
          return client.order.save();
        })
    })
    // .catch(err => console.log(err));
}
  

Я знаю, что нужны два маршрута: один для отображения таблицы со всеми доступными продуктами и один для отображения корзины с заказанными товарами.

 // Get all products
app.get('/products', function(req, res) {
  Product.find({})
    .exec()
    .then(products => res.render('products.ejs', {allProducts: products}))
    .catch(err => res.json({errors: err}));
});

// Order a product
app.get('/products/:productId/order', function(req, res) {
  req.user = {id: ""} /* id of the client, or the logged in user if you're using passeport or some other auth manager */
  Client.findOne({_id: req.user.id})
    .exec()
    .then(client => {
      if(client.order) {
        return addToOrder(client.id, req.params.productId)
          .then(order => res.render('cart.ejs', {order: order}))// render cart with the order
      } else {
        return createOrder(client.id, req.params.productId)
          .then(order => res.json('cart.ejs', {order: order}))
      }
    })
    .catch(err => res.json({errors: err}));
})
  

Мне нужно два (отображаемых моими обработчиками маршрутов):

 // /views/products.ejs
<div>
      <table>
        <% allProducts.forEach(function(product) { %>
          <tr>
            <th>name</th>
          </tr>
          <tr>
            <td><%= product.name %></td>
            <td><a href=<%=`/products/${product.id}/order`%>> Order </a> </td>
          <tr>
        <% }) %>
      </table>
    </div>


// views/cart.ejs
<div>
  <table>
    <% order.products.forEach(function(product) { %>
      <tr>
        <th>name</th>
      </tr>
      <tr>
        <td><%= product.name %></td>
      <tr>
    <% }) %>
  </table>
</div>
  

Я надеюсь, что это поможет.