rails db:migrate でカラム追加エラーが発生したので格闘させていただきました。





## 背景

とあるテーブルにカラムを追加し、バリデーションの追加やViewの修正を行った上でrails s したところ`ActiveRecord::PendingMigrationError`といったエラーが出た。

調べてみると、カラムの追加用に作成したマイグレーションファイルの実行がエラーしていた模様。

ターミナルで`rails db:migrate` 実行時にエラーログが出力されていたのを見落としていた。。

解決策は調べればすぐ見つかったが、テーブルをリセットする方法であったこともあり原因を掘り下げてみることにした。（今回はテストデータすらない状況だったので問題なかったが、リセットしたくない状況で発生したら嫌だし、再発防止策があればなという思いから。）

### エラー内容

```
$ rails db:migrate
== 20190503225002 AddTitleToMesasages: migrating ==============================
-- add_column(:mesasages, :title, :string)
rails aborted!
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: Table 'tr_ms_board_development.mesasages' doesn't exist: ALTER TABLE `mesasages` ADD `title` varchar(255)
（省略）

Caused by:
ActiveRecord::StatementInvalid: Mysql2::Error: Table 'tr_ms_board_development.mesasages' doesn't exist: ALTER TABLE `mesasages` ADD `title` varchar(255)
（省略）

Caused by:
Mysql2::Error: Table 'tr_ms_board_development.mesasages' doesn't exist
（省略）
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
```

Messagesテーブルにカラム「title」を追加しようとした際にエラーが発生している。

- StandardError が発生しておるのか。。

- StatementInvalid ってナニモノ。。

- ALTER TABLE がエラーになっていることはよくわかった。。

- またMysql2 由来のエラーかな？（前回はbundle install でエラーが発生した）

  

### 解消方法（Google先生の教え）

```
$ rake db:migrate:reset
$ rake db:migrate
```

どうやら上記コマンドを実行することで解決するらしいことがわかった。

が、リセットしてテーブル再作成したら上手くいく、というのは少々強引な解消法だったのでもう少し掘り下げてみることに。

## 原因特定と解消の流れ

### 原因はタイプミス！！

恥ずかしながら、今回のエラーの原因はテーブル名のスペルミスだった。。。掘り下げるどころか、ただのタイプミスだったので反省しつつ、下記流れで解消していった。

​`正）messages　誤）mesasages`

### 解消のためにやったこと

結果的に、Google先生に教えてもらった解消法（リセットしてマイグレーション再実行）はやってない。

#### タイプミスを修正してリトライ

マイグレーションファイル内のタイプミス部分を修正して、改めてマイグレーションの実行をやってみたがダメだった。どうやら、タイプミスした状態でマイグレーションファイルが認識されており、部分的に訂正したことにより不整合が発生している模様。（当たり前か。）

#### マイグレーションのstatus を確認

マイグレーションを削除してやり直す必要があるなと思い、まずは現状の確認から。

マイグレーションがどこまで反映されているか、確認。（カラムの追加が失敗しているため確認するまでもないが念の為）

```
$ rails db:migrate:status
database: tr_ms_board_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20190503004114  Create messages
  down    20190503225002  Add title to mesasage
```

上記結果から、カラム「title」の追加は無事（笑）、失敗していることを確認。

#### マイグレーションの削除

```
$ rails destroy migration AddTitleToMesasages
      invoke  active_record
      remove    db/migrate/20190503225002_add_title_to_mesasages.rb
```

上記コマンドにより削除完了。

不要になったマイグレーションファイルを削除する場合は、`rails destroy migration [作成したマイグレーションファイルのClass名]` によって削除が可能。

ここでの注意点としては、タイプミスした際に作成されたClass名を指定する必要があること。正しいClass名``でコマンドを実行すると、以下のように”見知らぬ”マイグレーションファイルがremove された状態となる。

```
$ rails destroy migration AddTitleToMessages
      invoke  active_record
      remove    db/migrate/20190504001410_add_title_to_messages.rb
```

マイグレーションファイルの削除が完了したところで、改めてstatus を確認してみると以下の通り。マイグレーションファイルは一つしか残っていないことがわかる。

```
$ rails db:migrate:status                    
database: tr_ms_board_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20190503004114  Create messages
```





#### マイグレーションの実行

まずはカラム追加用のマイグレーションファイルを作成。

```
$ rails g migration AddTitleToMessages title:string
      invoke  active_record
      create    db/migrate/20190504002340_add_title_to_messages.rb
```

その後、マイグレーションの実行。

```
$ rails db:migrate
== 20190504002340 AddTitleToMessages: migrating ===============================
-- add_column(:messages, :title, :string)
   -> 0.0670s
== 20190504002340 AddTitleToMessages: migrated (0.0671s) ======================
```



念の為、status の確認。（覚えたてのコマンドを実行したいだけ笑）

```
$ rails db:migrate:status

database: tr_ms_board_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20190503004114  Create messages
   up     20190504002340  Add title to messages
```

反映できてるー！！ことを確認し、今回のエラーは解決済みとする。



## 今回の学び

前述の内容以外に、学んだことについてメモ。

### マイグレーション up/down の方法

マイグレーションファイルを反映/取消し（up/down）させるためには下記コマンド実行により可能。

- UPさせたいとき｜`$ rails db:migrate:up VERSION=[バージョン番号]`

- DOWNさせたいとき｜`$ rails db:migrate:down VERSION=[バージョン番号]`

コマンド内で指定するバージョン番号は、マイグレーションファイルのファイル名の先頭についている番号のこと。

以下、試しにDOWNさせてUPさせた結果。（今回の場合、UPの部分は`$ rails db:migrate`でもOK）

```
$ rails db:migrate:down VERSION=20190504002340
== 20190504002340 AddTitleToMessages: reverting ===============================
-- remove_column(:messages, :title, :string)
   -> 0.0639s
== 20190504002340 AddTitleToMessages: reverted (0.0675s) ======================

$ rails db:migrate:status                     
database: tr_ms_board_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20190503004114  Create messages
  down    20190504002340  Add title to messages
  

$ rails db:migrate:up VERSION=20190504002340
== 20190504002340 AddTitleToMessages: migrating ===============================
-- add_column(:messages, :title, :string)
   -> 0.0162s
== 20190504002340 AddTitleToMessages: migrated (0.0163s) ======================

$ rails db:migrate:status                   
database: tr_ms_board_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20190503004114  Create messages
   up     20190504002340  Add title to messages
```



### テーブル参照方法


```
$ rails db

mysql> show tables;
+-----------------------------------+
| Tables_in_tr_ms_board_development |
+-----------------------------------+
| ar_internal_metadata              |
| messages                          |
| schema_migrations                 |
+-----------------------------------+
3 rows in set (0.00 sec)

mysql> desc messages;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| content    | varchar(255) | YES  |     | NULL    |                |
| created_at | datetime     | NO   |     | NULL    |                |
| updated_at | datetime     | NO   |     | NULL    |                |
| title      | varchar(255) | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+
5 rows in set (0.01 sec)
```



### まとめ

#### コマンドの実行結果は確認すること

割と当たり前のことだが、自分が実行したコマンドが成功したのか失敗したのかぐらいは確認すべきだ。

実行して終わり、とせずに、「上手くいってるよね？」を気にしようと思った。

#### タイプミスを気づくチャンスはあった

IDEとしてRubyMine を利用しているが、タイプミス部分は下線が引かれていたりしていることに気づいた。このようなIDEのフォローを無駄にしないようにしたいと思った。
ちなみに、「⌥Enter / Alt+Enter」を押すと、利用可能なオススメアクションを表示する機能があるらしい。

#### マイグレーションの取り扱いが少しわかった（気がする）

  status の見方や削除の方法など、初めての操作があって学ぶことが多かった。

  実際の開発ではmigration をup/down することがあると思うので、その操作方法についても知ることができたのはよかった。タイプミスに少しだけ感謝しておこう。