express

網頁

Sequelize 筆記

// db.js

const { Sequelize } = require('sequelize');

const sequelize = new Sequelize('database', 'root', '1234', {
  dialect: 'mysql',
  timezone: '+08:00',
  define: {
    underscored: true, // 欄位有下㡳線
    freezeTableName: true, // 不要自動改變 table 名稱
  },
});

module.exports = sequelize;

// app.js

sequelize
  .sync()
  .then(() => {
    app.listen(3000, () => {
      console.log('listening on port 3000');
    });
  })
  .catch((err) => {
    console.log(err);
  });

// model

const TeamTaiwan = sequelize.define(
  'teamTaiwan',
  { ... },
  { tableName: 'team_taiwan' }
);

module.exports = TeamTaiwan;

---

const TaiwanPlayer = sequelize.define(
  'taiwanPlayer',
  { ... },
  { tableName: 'taiwan_player' }
);

module.exports = TaiwanPlayer;

// TeamTaiwan 跟 TaiwanPlayer 是一對多的關係

TeamTaiwan.hasMany(TaiwanPlayer);
TaiwanPlayer.belongsTo(TeamTaiwan);

新增 TaiwanPlayer 的 Foreign Key(team_taiwan_id),在程式裡會變成 teamTaiwanId

TaiwanPlayer.create({
  name: formData.name,
  teamTaiwanId: teamTaiwanId,
})
  .then(...)
  .catch(...);

有用到下面的 sequelize.fn, sequelize.col 語法時,取欄位值有二個方法:

TaiwanPlayer.findAll({
  attributes: [[sequelize.fn('COUNT', sequelize.col('name')), 'count_name']],
})

---

JSON.parse(JSON.stringify(data[0]))

或

data[0].get().count_name

網頁

使用 express-validator

// router

const adminValidator = require('../validators/admin.validator');

...

router.post(
  '/shop-type/create',
  adminValidator.checkShopTypeFormData(),
  shopTypeController.createShopType
);
// admin.validator.js

const { body } = require('express-validator');

function checkShopTypeFormData() {
  return [body('name').trim().notEmpty().withMessage('請輸入商店類別')];
}

function checkShopFormData() {
  return [
    body('name').trim().notEmpty().withMessage('請輸入商店'),
    body('phone').trim().notEmpty().withMessage('請輸入電話'),
    body('note').optional().trim(),
    body('type').isNumeric().withMessage('請選擇類別'),
  ];
}

module.exports = { checkShopTypeFormData, checkShopFormData };
// controller

const { matchedData, validationResult } = require('express-validator');

...

const result = validationResult(req);

if (!result.isEmpty()) {
  ShopType.findAll()
    .then((shopTypeList) => {
      res.render('admin/shop/createShopForm', {
        errors: result.array(),
        old: req.body,
        shopTypeList,
      });
    })
    .catch((err) => {
      console.log(err);
    });
} else {
  const formData = matchedData(req);

  ShopType.findByPk(formData.type)
    .then((data) => {
      if (data === null) {
        res.send('404 Not Found');
        return;
      }

      return Shop.create({
        name: formData.name,
        phone: formData.phone,
        note: formData.note,
        shopTypeId: formData.type,
      });
    })
    .then((data) => {
      if (data) {
        res.redirect('/admin/shops');
      }
    })
    .catch((err) => {
      console.log(err);
    });
}
// view

<% if (errors.length > 0) { %>
<div>
  <% errors.forEach((err) => { %>
  <p><%= err.msg %></p>
  <% }) %>
</div>
<% } %>
返回頂端