#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>
Я надеюсь, что это поможет.