【備忘録・Rails】Mysql2::Error: Specified key was too long; max key length is 767 bytes エラーを解決する方法

## はじめに

こんにちは、だいごです。
今回はタイトルのエラーを解決する方法をまとめていきます。
よかったらご覧ください。

## エラーについて

まず、今回発生したエラーはターミナルにて**rails db:migrate**を実行した際に発生しました。
エラー文は以下に記します。

```zsh:ターミナル
ユーザー名@コンピュータ名 カレントディレクトリ % rails db:migrate

# エラー文
== 20220413235353 DeviseCreateUsers: migrating ================================
-- create_table(:users)
   -> 0.1096s
-- add_index(:users, :email, {:unique=>true})
rails aborted!
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: Specified key was too long; max key length is 767 bytes
/Users/○○/○○/○○/db/migrate/20220413235353_devise_create_users.rb:45:in `change'
/Users/○○/○○/○○/bin/rails:9:in `<top (required)>'
/Users/○○/○○/○○/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'

# 省略
```

このエラーは「Mysql2に、格納できる文字データは、767バイトまでで、このままでは、Mysqlにマイグレーションできない」という意味になります。

## エラーが発生した原因

このエラーが発生した原因は**database.yml**にあります。

```yml:datebase.yml
# 省略

default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  socket: /tmp/mysql.sock

# 省略
```

注目すべきなのは**encoding: utf8mb4**の部分です。
ここでは、文字コードを指定しているのですが、今の**utf8mb4**では１文字４バイトとなります。
MySQLではstring型を指定した場合、デフォルトで255文字となるため、
<b>255×4=1020(バイト)</b>となり、767バイトを超えてしまうので、エラーが発生してしまったということです。

## エラー解決の流れ

ここからは実際にエラーを解決していきます。
エラーの解決方法としては、文字コードを変えて767バイトを超えないようにする方法を使用します。

まずは、datebase.ymlの記述を変更します。

```yml:database.yml
# 省略

default: &default
  adapter: mysql2
  encoding: utf8  #utf8に変更
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  socket: /tmp/mysql.sock

# 省略
```

ここでは、**encoding: utf8**に変更しています。
**utf8**では１文字３バイトとなり、<b>255×3=765(バイト)</b>で、
767バイトの範囲内で収めることができています。
これでエラーの原因を排除することができました。

次に、DBを作り直していきます。
まず、マイグレーションファイルの状態を確認します。

```zsh:ターミナル
ユーザー名@コンピュータ名 カレントディレクトリ % rails db:migrate:status

# 出力結果
database: ○○_development

 Status   Migration ID    Migration Name
--------------------------------------------------
  down    20220413235353  Devise create users
```

マイグレーションファイルが**down**になっていることが確認できたら、
**rails db:reset**コマンドを実行していきます。
これは、DBを一度削除し、再度生成するコマンドです。

```zsh:ターミナル
ユーザー名@コンピュータ名 カレントディレクトリ % rails db:reset

# 出力結果
Dropped database '○○_development'
Dropped database '○○_test'
Created database '○○_development'
Created database '○○_test'
/Users/○○/○○/○○/db/schema.rb doesn't exist yet. Run `rails db:migrate` to create it, then try again. If you do not intend to use a database, you should instead alter /Users/○○/○○/○○/config/application.rb to limit the frameworks that will be loaded.
```

この後、再び**rails db:migrate**を実行します。

```zsh:ターミナル
ユーザー名@コンピュータ名 カレントディレクトリ % rails db:migrate

# 出力結果
== 20220413235353 DeviseCreateUsers: migrating ================================
-- create_table(:users)
   -> 0.0209s
-- add_index(:users, :email, {:unique=>true})
   -> 0.0514s
-- add_index(:users, :reset_password_token, {:unique=>true})
   -> 0.0193s
== 20220413235353 DeviseCreateUsers: migrated (0.0975s) =======================
```

以上で、エラーの解消は完了です。

## 終わりに
今回はエラーの解決方法についてまとめました。
他にも解決方法があるみたいなので、またエラーが出た時にやってみようと思います。
ご指摘・コメントお待ちしております。
ありがとうございました。