node.js超入門ノート11(Sequelizeでのバリデーション編)

# バリデーション
## モデルのバリデーション
以下のように修正します。

```javascript:models/user.js
'use strict';
module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define('User', {
    name: {
      type:DataTypes.STRING,
      validate: {
        notEmpty: true
      }
    },
    pass: {
      type: DataTypes.STRING,
      validate: {
        notEmpty: true
      }
    },
    mail: {
      type: DataTypes.STRING,
      validate: {
        isEmail: true
      }
    },
    age: {
      type: DataTypes.STRING,
      validate: {
        isInt: true,
        min: 0
      }
    }
  }, {});
  User.associate = function(models) {
    // associations can be defined here
  };
  return User;
};
```
validateの例は以下のようになります。

|validate|意味|
|---|---|
|notEmpty  |未入力の禁止  |
|isEmail  |メールアドレス形式のみ許可  |
|isInt  |整数値のみ許可  |
|min  |最小値の設定  |
## User作成処理のバリデーション
以下を修正します。

```javascript:routes/users.js
router.get('/add',(req, res, next) => {
  var data = {
    title: 'Users/Add',
    form: new db.User(),
    err:null
  }
  res.render('users/add', data);
});

router.post('/add',(req, res, next) => {
  const form = {
    name: req.body.name,
    pass: req.body.pass,
    mail: req.body.mail,
    age: req.body.age
  };
  db.sequelize.sync()
    .then(() => db.User.create(form)
    .then(usr => {
      res.redirect('/users');
    })
    .catch(err => {
      var data = {
        title: 'Users/Add',
        form: form,
        err: err
      }
      res.render('users/add', data);
    })
    )
});
```
## テンプレートのエラー表示
テンプレートにエラーの表示を追加します。

```html:views/users/add.ejs
<!DOCTYPE html>
<html lang="ja">

    <head>
        <meta charset="UTF-8">
        <meta http-equiv="content-type" content="text/html">
        <title><%= title %></title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" crossorigin="anonymous">
        <link rel="stylesheet" href="/stylesheets/style.css" />
    </head>

    <body class="container">

        <header>
            <h1 class="display-4">
                <%= title %>
            </h1>
        </header>
        <div role="main">
            <ol class="text-danger">
                <% if (err!=null) {for (let i in err.errors) { %>
                <li><%= err.errors[i].message %></li>
                <% }} %>
            </ol>
            <form action="/users/add" method="post">
                <div class="form-group">
                    <label for="name">NAME</label>
                    <input type="text" name="name" id="name" value="<%=form.name %>" class="form-control">
                    <ul class="text-danger">
                        <% if (err!=null) {for (let i in err.get("name")) { %>
                        <li><%= err.get("name")[i].message %></li>
                        <% }} %>
                    </ul>
                </div>
                <div class="form-group">
                    <label for="pass">PASSWORD</label>
                    <input type="password" name="pass" id="pass" value="<%=form.pass %>" class="form-control">
                    <ul class="text-danger">
                        <% if (err!=null) {for (let i in err.get("pass")) { %>
                        <li><%= err.get("pass")[i].message %></li>
                        <% }} %>
                    </ul>
                </div>
                <div class="form-group">
                    <label for="mail">MAIL</label>
                    <input type="text" name="mail" id="mail" value="<%=form.mail %>" class="form-control">
                    <ul class="text-danger">
                        <% if (err!=null) {for (let i in err.get("mail")) { %>
                        <li><%= err.get("mail")[i].message %></li>
                        <% }} %>
                    </ul>
                </div>
                <div class="form-group">
                    <label for="age">AGE</label>
                    <input type="number" name="age" id="age" value="<%=form.age %>" class="form-control">
                    <ul class="text-danger">
                        <% if (err!=null) {for (let i in err.get("age")) { %>
                        <li><%= err.get("age")[i].message %></li>
                        <% }} %>
                    </ul>
                </div>
                <input type="submit" value="作成" class="btn btn-primary">
            </form>
        </div>
    </body>
</html>
```

http://localhost:3000/users/add

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111200/bda77a6a-a7e0-d9e5-7bdb-f3714034a1a5.png)

## エラーメッセージを日本語に変更
以下を修正します。

```javascript:models/user.js
'use strict';
module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define('User', {
    name: {
      type:DataTypes.STRING,
      validate: {
        notEmpty: {
          msg: "名前は必ず入力してください。"
        }
      }
    },
    pass: {
      type: DataTypes.STRING,
      validate: {
        notEmpty: {
          msg: "パスワードは必ず入力してください。"
        }
      }
    },
    mail: {
      type: DataTypes.STRING,
      validate: {
        isEmail: {
          msg: "メールアドレスを入力して下さい。"
        }
      }
    },
    age: {
      type: DataTypes.STRING,
      validate: {
        isInt: {
          msg: "ゼロ以上の値が必要です。"
        },
        min: {
          args: [0],
          msg: "ゼロ以上の値が必要です。"
        }
      }
    }
  }, {});
  User.associate = function(models) {
    // associations can be defined here
  };
  return User;
};
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111200/7bd2cfd7-e41b-dea4-2520-5bbb85064f6a.png)
バリデーション一覧は以下のPer-attribute validationsから見れます。

https://sequelize.org/master/manual/validations-and-constraints.html

https://qiita.com/Glider2355/items/4da3b2220886b6da8dcd