14
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Sequelizeのモデル定義をclass構文で書く方法

Last updated at Posted at 2018-01-17

Sequelizeのクラス定義をdefineメソッドで書いていたのですが、バージョン4からclass定義の構文で書けるというウワサを聞いて試してみようと思いました。
しかしいくら調べてもちゃんとした書き方が見つからず苦労したのでまとめておきます。

#結論
こんな感じです

models/user.js
class User extends Sequelize.Model {

  // クラスメソッド
  static findByEmail(email) {
    return this.findOne({ where: { email: email }})
  }

  // インスタンスメソッド
  verifyPassword(password) {
    return bcrypt.compare(password, this.password_hash)
  }
}

User.init(
  // フィールド
  {
    id: {
      type: Sequelize.INTEGER,
      primaryKey: true,
      autoIncrement: true,
      allowNull: false
    },
    name: {
      type: Sequelize.STRING,
      allowNull: false
    },
    password_hash: {
      type: Sequelize.STRING,
      allowNull: false
    },
    email: {
      type: Sequelize.STRING,
      allowNull: false
    }
  }, {
        // オプション
    freezeTableName: true,
    underscored: true,
    timestamps: true,
    sequelize
  }
)

クラスメソッド

クラスメソッドはstaticをつけたメソッドとして書くことができます。
staticメソッドの中でthisUserクラスを指します。

従来の書き方
// クラスメソッド
User.findByEmail = function(email) {
  return this.findOne({ where: { email: email }})
}
classを使った書き方
class User extends Sequelize.Model {

  static findByEmail(email) {
    return this.findOne({ where: { email: email }})
  }

}

インスタンスメソッド

インスタンスメソッドは、モデルのプロトタイプに関数を登録していたのが、普通のメソッド定義になりました。
thisUserクラスのインスタンスを指します。

従来の書き方
// インスタンスメソッド
User.prototype.verifyPassword = function(password) {
  return bcrypt.compare(password, this.password_hash)
}
classを使った書き方
class User extends Sequelize.Model {

  // インスタンスメソッド
  verifyPassword(password) {
   return bcrypt.compare(password, this.password_hash)
  }

}

クラスメソッドもそうなのですが、従来の書き方でアロー演算子を使った書き方をしていたら、thisがグローバルオブジェクトになっていて困りました。functionを使って書かないとthisはインスタンスを指してくれないみたいです。
functionキーワードはもう使うな」って偉い人が言ってましたが、何も考えずにアロー演算子でインスタンスメソッドを書いてしまうとthisがインスタンスを指してくれないので、オブジェクト指向なものを書く時はclass構文を使っていった方がよさそうです。

フィールド定義とオプション

従来の書き方
sequelize.define('テーブル名', {フィールド定義}, {オプション})
classを使った書き方
User.init({フィールド定義}, {オプション})

Sequelizeバージョン4の新機能 っていうところに書いてましたが、この書き方を見つけることができなくて、長いこと苦しんでいました。
オプションにはsequelizeというキーでSequelizeのインスタンスを指定しないとエラーになります。これはよくわかんなかったですが、エラーになるので指定しましょう。

{
   // オプション
  freezeTableName: true,
  underscored: true,
  timestamps: true,
  sequelize
}

実際に書き直した例

実際にモデルの定義をclass構文で書き直したときのコミットを貼っておきます。
https://github.com/mktoho12/myapp/commit/09f4c44a53c1d4f5453a122d6fcfa08c649b277f

現時点での各バージョン

  • node 9.4.0
  • sequelize 4.31.1
14
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?