ExpressでMongooseを使う part5
農産物の商品管理アプリ作成の続きです。
今回は、商品の編集・更新ができるようにしていきます。
ルーティングを追加していきます。
・index.js
const express = require('express');
const app = express();
const path = require('path');
const mongoose = require('mongoose');
//method-overrideの宣言
const methodOverride = require('method-override');
const Product = require('./models/product');
{ useNewUrlParser: true, useUnifiedTopology: true })
app.set('view engine', 'ejs');
app.use(express.urlencoded({ extended: true }));
//リクエストはpostかgetのみなのでPUT, DELETEを使えるようにオーバーライドしておく
app.use(methodOverride('_method'))
//カテゴリを配列にしておき、ejsの方でループさせることで管理
const categories = ['果物', '野菜', '乳製品'];
//商品一覧
app.get('/products', async (req, res) => {
const products = await Product.find({})
res.render('products/index', { products});
})
//商品登録フォーム
app.get('/products/new', (req, res) => {
res.render('products/new', { categories });
})
app.post('/products', async (req, res) => {
const newProduct = new Product(req.body);
await newProduct.save();
res.redirect(`/products/${newProduct._id}`);
})
//商品詳細ページ
app.get('/products/:id', async (req, res) => {
//id取得
const { id } = req.params;
const product = await Product.findById(id).populate('farm', 'name');
res.render('products/show', { product });
})
//商品の更新
app.get('/products/:id/edit', async (req, res) => {
//id取得
const { id } = req.params;
const product = await Product.findById(id);
res.render('products/edit', { product, categories });
})
//編集のリクエストエンドポイント
app.put('/products/:id', async (req, res) => {
const { id } = req.params;
//findByIdAndUpdateは更新前のものが渡されるので、new: trueで更新後を取得する
const product = await Product.findByIdAndUpdate(id, req.body,
{ runValidators: true, new: true });
res.redirect(`/products/${product._id}`);
})
app.listen(3000, () => {
console.log('ポート3000で待機');
})
※編集のリクエストのエンドポイントのルーティングを記述する際の注意点です。
フォームのリクエストは「GET」か「POST」しか投げることができません。
そこで使用するのが、「method-override」です。これを使うことで「GET」か
「POST」以外のリクエストもフォームから投げれるようになります。
また「findByIdAndUpdate( )」の第三引数にも、「 runValidators 」をtrueにするこ
とで更新の際にバリデーションが走るように設定もしておきます。
次は編集画面のテンプレートを作成します。
・edit.ejs
<!DOCTYPE html>
<html lang="ja">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>商品の編集</title>
</head>
<body>
<h1>商品の編集</h1>
<form action="/products/<%= product._id %>?_method=PUT" method="POST">
<label for="name">商品名</label>
<input type="text" name="name" id="name" placeholder="商品名"
<label for="price">価格</label>
<input type="number" name="price" id="price" placeholder="価格"
<label for="category">カテゴリ</label>
<select name="category" id="category">
<% for(let category of categories) {%>
<%= category %>
</option>
<% } %>>
</select>
<button>登録</button>
</form>
<a href="/products/<%= product._id %>"> キャンセル</a>
</body>
</html>
ここまで記述できれば実際の画面で確認してみます
編集フォームへ遷移します。登録ボタンを押下
無事に商品の更新がされています。
*1:) => {
console.log('MongoDBコネクションOK!!');
})
.catch(err => {
console.log('MongoDBコネクションエラー!!!');
console.log(err);
});
app.set('views', path.join(__dirname, 'views'