[Express.js][Sequelize] 親レコードの削除時に子レコードも削除（ cascade削除 ）する

[Express.js(ejs) + Sequelize(MySQL)でrailsのscaffoldアプリを作る](https://qiita.com/mazeltov7/items/306cf93af50c0810c9b4)　の記事を参考に　User (親) と 各 User に紐付く Comment (子) の構成を持つアプリケーションを作りました。

このアプリケーションにて、親の User を削除した際に、その User に紐付く子の Comment 群も削除する Cascade 削除を行う方法でハマったので記録します。

### 環境
- Node.js: v10.5.0
- Express.js: 4.16.0
- Sequelize: 4.0.0
- MySQL: 5.6.40

## 採用した方法 ( migration の addConstraint で cascade 定義する )

migration の addConstraint で cascade 定義した foreign key を設定します。

まず、 migration を新規作成します。

```
$ sequelize migration:create --name AddConstraintToComment
```
```migrations/20180728081647-AddConstraintToComment.js
'use strict';

module.exports = {
  up: (queryInterface, Sequelize) => {
    /*
      Add altering commands here.
      Return a promise to correctly handle asynchronicity.

      Example:
      return queryInterface.createTable('users', { id: Sequelize.INTEGER });
    */
    return Promise.all([
      queryInterface.addConstraint('Comments', ['user_id'], {
        type: 'foreign key',
        name: 'fk_comments_users',
        references: {
          table: 'Users',
          field: 'id'
        },
        onDelete: 'cascade',
        onUpdate: 'cascade'
      })
    ]);
  },

  down: (queryInterface, Sequelize) => {
    /*
      Add reverting commands here.
      Return a promise to correctly handle asynchronicity.

      Example:
      return queryInterface.dropTable('users');
    */
    return queryInterface.removeConstraint('Comments', 'fk_comments_users');
  }
};
```

addConstraint のオプションで `onDelete : 'cascade'` を指定するところがポイントです。

migration を実行します。

```
$ sequelize db:migrate
```

実行が成功すると、以下のようなテーブル定義になっていることが確認できます ( MySQL にて)。

```
mysql> show create table Comments;
+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                   |
+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Comments | CREATE TABLE `Comments` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `content` text,
  `createdAt` datetime NOT NULL,
  `updatedAt` datetime NOT NULL,
  `user_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_comments_users` (`user_id`),
  CONSTRAINT `fk_comments_users` FOREIGN KEY (`user_id`) REFERENCES `Users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8 |
+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
```

CASCADE 制約によって、 User を 削除した時に、紐付く Comment も削除されるようになります。

## 動かなかった方法

[マニュアル](http://sequelize.readthedocs.io/en/latest/api/associations/index.html?highlight=onDelete#hasmanytarget-options) や [チュートリアル](http://docs.sequelizejs.com/manual/tutorial/hooks.html#associations) 、 [Stack Overflow](https://stackoverflow.com/questions/23634139/sequelize-ondelete-not-working) などによると、 model にて、 hasMany メソッドに次のように onDelete オプションと hooks オプションを与えれば cascade 削除が動くようなのですが、動作しませんでした。

```
Users.hasMany(Comments, { onDelete: 'cascade', hooks: true });
```

より、具体的な記述は次の通りです。

```models/user.js
'use strict';
module.exports = (sequelize, DataTypes) => {
  var User = sequelize.define('User', {
    name: DataTypes.STRING,
    age: DataTypes.INTEGER
  }, {});
  User.associate = function(models) {
    // associations can be defined here
    User.hasMany(models.Comment, {
      foreignKey: 'user_id',
      onDelete: 'cascade',
      hooks: true
    });
  };
  return User;
}
```

何か知見をお持ちの方があれば、ご教示いただけるとありがたいです。