Skip to content

Latest commit

 

History

History
448 lines (375 loc) · 10.9 KB

File metadata and controls

448 lines (375 loc) · 10.9 KB

Mongoose

몽구스란?

ODM (A Object-Document Mapping Library)

시퀄라이저랑 비슷하게 mogoDB를 자바스크립트로 편하게 짤 수 있도록 해주는 모듈

mongoose 초기 설정

  1. $ npm i --save mongoose

  2. app.js에 mongose연결하기

    const mongoose = rerquire('mongoose');
    
    mongoose
      .connect('mongodb://localhost:27017/test')
      .then(result => {
        app.listen(4000);
      })
      .catch(err => {
        console.log(err);
      });
    
    
  3. models/product.js 에 제품 스키마 생성하기

    const mongoose = require('mongoose');
    
    // 새로운 스키마 생성
    const Schema = mongoose.Schema;
    
    // 키 밸류로 스키마 정의하기
    const productSchema = new Schema({
      title: {
        type: String,
        required: true
      },
      price: {
        type: Number,
        require: true
      },
      description: {
        type: String,
        reqruie: true
      },
      imageUrl: {
        type: String,
        reqruie: true
      }
    });
    
    module.exports = mongoose.model('Product', productSchema);
    
  4. controllers/admin.js 에 postAddProduct 수정

    const Product = require('../models/product');
    
    exports.postAddProduct = (req, res, next) => {
      const title = req.body.title;
      const imageUrl = req.body.imageUrl;
      const price = req.body.price;
      const description = req.body.description;
       // mongoose에서 정의한 model을 가져와서 새 객체 만들기
      const product = new Product({
        title,
        price,
        description,
        imageUrl
      });
      product
        .save() // mongoose에서 제공하는 메서드
        .then(result => {
          console.log('Created Product');
          res.redirect('/');
        })
        .catch(err => {
          console.log(err);
        });
    };
    
    • 이후 add-product 페이지에서 제품을 추가하면 데이터베이스에 데이터가 들어가 있다.

데이터베이스에서 제품 가져오기

  1. controllers/shop.js 에 getProducts 함수 수정

    const Product = require('../models/product');
    
    exports.getProducts = (req, res, next) => {
      Product.find()
        .then(products => {
          console.log(products);
          res.render('shop/product-list', {
            prods: products,
            pageTitle: 'All Products',
            path: '/products'
          });
        })
        .catch(err => {
          console.log(err);
        });
    };
    
  2. detail 페이지를 위해 controlelrs/shop.js getProduct 함수 수정

    exports.getProduct = (req, res, next) => {
      const prodId = req.params.productId;
      Product.findById(prodId) //mongoose 메서드. Id를 자동으로 mongodb.ObjectId 로 바꿔줌
        .then(product => {
          res.render('shop/product-detail', {
            product: product,
            pageTitle: product.title,
            path: '/products'
          });
        })
        .catch(err => console.log(err));
    };
    
    

제품 수정, 삭제 하기

  1. controllers/admin.js postEditProduct 함수 수정하기

    exports.postEditProduct = (req, res, next) => {
      const prodId = req.body.productId;
      const updatedTitle = req.body.title;
      const updatedPrice = req.body.price;
      const updatedDesc = req.body.description;
      const updatedImageUrl = req.body.imageUrl;
    
      Product.findById(prodId)
        .then(product => {
          // mongoose에서 가져온 product
          // mognoose에서 save를 사용하게 되면 자동으로 기존 데이터가 없으면 저장, 있으면 수정함.
          product.title = updatedTitle;
          product.price = updatedPrice;
          product.description = updatedDesc;
          product.imageUrl = updatedImageUrl;
          return product.save();
        })
        .then(result => {
          console.log('Updated');
          res.redirect('/admin/products');
        })
        .catch(err => {
          console.log(err);
        });
    };
    
  2. 삭제하기 위해 controllers/admin.js에서 postDeleteProduct함수 수정

    exports.postDeleteProduct = (req, res, next) => {
      const prodId = req.body.productId;
      Product.findByIdAndRemove(prodId)
        .then(() => {
          res.redirect('/admin/products');
        })
        .catch(err => console.log(err));
    };
    
    

User 넣기

  1. models/user.js 에 User 스키마 정의하기

    const mongoose = require('mongoose');
    
    const Schema = mongoose.Schema;
    
    const userSchema = new Schema({
      name: {
        type: String,
        require: TextTrackCue
      },
      email: {
        type: String,
        require: true
      },
      cart: {
        items: [
          {
            productId: { type: Schema.Types.ObjectId, required: true },
            quantity: { type: Number, required: true }
          }
        ]
      }
    });
    
    module.exports = mongoose.model('User', userSchema);
    
  2. 서버 시작할 때 user 만들기

    mongoose
      .connect('mongodb://localhost:27017/test')
      .then(result => {
        User.findOne().then(user => {
          if (!user) {
            const user = new User({
              name: 'MJ',
              email: 'busanminjae@naver.com',
              cart: {
                items: []
              }
            });
            user.save();
          }
        });
    
        app.listen(4000);
      })
      .catch(err => {
        console.log(err);
      });
    
    
  3. contorllers/admin.js 에 getProducts 수정하기

    exports.getProducts = (req, res, next) => {
      Product.find()
        //.select('title price imageUrl -_id') => 이런식으로 가저올 데이터 적어주고 
        //										필요없는 데이터는 앞에 - 넣기
        // .populate('userId', 'name') // mongoose 메서드로서 조회한 데이터를 가져옴
        .then(products => {
          console.log(products);
          res.render('admin/products', {
            prods: products,
            pageTitle: 'Admin Products',
            path: '/admin/products'
          });
        })
        .catch(err => {
          console.log(err);
        });
    };
    

쇼핑카트

  1. models/user.js 기존에 정의 했던 addToCart 함수를 userSchema 인스턴스에 재사용하자.

    userSchema.methods.addToCart = product => {
      // cart에 제품 있는지 조회 ? 양수 : -1
      const cartProductIndex = this.cart.items.findIndex(cp => {
        return cp.productId.toString() === product._id.toString();
      });
      let newQuantity = 1;
      const updatedCartItems = [...this.cart.items];
    
      // cart에 제품 있으면
      if (cartProductIndex >= 0) {
        newQuantity = this.cart.items[cartProductIndex].quantity + 1;
        updatedCartItems[cartProductIndex].quantity = newQuantity;
    
        // cart에 제품 없으면
      } else {
        // 위 스키마에서 정의한 이름과 같아야한다.
        updatedCartItems.push({
          productId: product._id,
          quantity: newQuantity
        });
      }
      const updatedCart = {
        items: updatedCartItems
      };
      this.cart = updatedCart;
      return this.save();
    };
    

카트 삭제하기

  1. models/user.js removeFromCart 메서드 만들기

    userSchema.methods.removeFromCart = function(productId) {
      const updatedCartItems = this.cart.items.filter(item => {
        return item.productId.toString() !== productId.toString();
      });
      this.cart.items = updatedCartItems;
      return this.save();
    };
    

    삭제할 카트 놔두고 업데이트 하기

  2. controllers/shop.js 수정하기

    exports.postCartDeleteProduct = (req, res, next) => {
      const prodId = req.body.productId;
      req.user
        .removeFromCart(prodId)
        .then(result => {
          res.redirect('/cart');
        })
        .catch(err => {
          console.log(err);
        });
    };
    

Order 추가

  1. models/order.js 에 order 스키마 정의하기

    const mongoose = require('mongoose');
    
    const Schema = mongoose.Schema;
    const orderSchema = new Schema({
      products: [
        {
          productData: { type: Object, required: true },
          quantity: { type: Number, required: true }
        }
      ],
      user: {
        name: {
          type: String,
          required: true
        },
        userId: {
          type: Schema.Types.ObjectId,
          required: true,
          ref: 'User'
        }
      }
    });
    
    module.exports = mongoose.model('Order', orderSchema);
    
    
  2. controllers/shop.js 에 order 모델 가져오고 postOrder 작성하기

    exports.postOrder = (req, res, next) => {
      req.user
        .populate('cart.items.productId')
        .execPopulate()
        .then(user => {
          const products = user.cart.items.map(i => {
            // ._docs를 하게 되면 모든 정보 가져온다.
            return { quantity: i.quantity, product: { ...i.productId._doc } };
          });
          const order = new Order({
            user: {
              name: req.user.name,
              userId: req.user
            },
            products: products
          });
          return order.save();
        })
        .then(result => {
          res.redirect('/orders');
        })
        .catch(err => {
          console.log(err);
        });
    };
    
  3. 주문하고 카트 비우기

    • models/user.js 에 메소드 생성

      userSchema.methods.clearCart = function() {
        this.cart = { itmes: [] };
        return this.save();
      };
      
    • controllers/shop.js postOrder 수정

      exports.postOrder = (req, res, next) => {
        req.user
          .populate('cart.items.productId')
          .execPopulate()
          .then(user => {
            const products = user.cart.items.map(i => {
              // ._docs를 하게 되면 모든 정보 가져온다.
              return { quantity: i.quantity, product: { ...i.productId._doc } };
            });
            const order = new Order({
              user: {
                name: req.user.name,
                userId: req.user
              },
              products: products
            });
            return order.save();
          })
          .then(result => {
            return req.user.clearCart();
          })
          .then(() => {
            res.redirect('/orders');
          })
          .catch(err => {
            console.log(err);
          });
      };
      
  4. 주문 목록 보여주기

    • controllers/shop.js 에 getOrders 수정

      exports.getOrders = (req, res, next) => {
        Order.find({ 'user.userId': req.user._id }).then(orders => {
          res.render('shop/orders', {
            path: '/orders',
            pageTitle: 'your Orders',
            orders: orders
          });
        });
      };