開発環境のカラム情報が本番環境 AWS EC2のDBに反映されなかったときの対処法


<h1>はじめに</h1>
個人開発したアプリケーションをAWS EC2で本番環境にデプロイをしました。

その後、<b>追加機能としてチャットルーム機能を実装。roomsテーブルを追加しました。

<b>なので再びEC2にデプロイ。
EC2本番環境で新しい機能、rooms/newページでチャットルーム作成をして、rooms/createのページアクセスすると以下のエラーが発生。
<img src ='https://user-images.githubusercontent.com/58378273/95056184-4f496700-072f-11eb-9f67-3ebc5886198d.png'>room/createのページにアクセスできませんでした。（チャットルームが作成できない状況）

ポイントとして
<h3>・開発環境(localhost:3000)とherokuでは問題なくrooms/newからrooms/createにアクセスできる。でもEC2ではできない。</h3>　ということ。


<h5>今回の原因として、roomsテーブル作成後、新しくnameカラムを追加しました。<br>結果、そのカラム追加方法に原因があったようです。<br>そのためEC2のDBにnameカラム反映されなかったみたいでした。内容を詳しく後述します。</h5>
まず、使用している開発環境及び追加したテーブル&カラムは以下の通りです。


<h1>開発環境</h1>
Ruby 2.6.5
Ruby on Rails 6.0.3.7
MySQL  5.6.51
Github  2.30.1
heroku 7.54.0
AWS EC2

自動デプロイツール : Capistrano
Webサーバー : nginx
APサーバー     :Unicorn
<h1>追加したテーブル</h1>

## rooms

| Column  | Type       | Options           |
| --------| ---------- | ----------------- |
| name    | strings    | null: false       |

has_many: users through: :room_users
has_many: room_users

## room_users（中間テーブル）

| Column   | Type       | Options           |
| -------- | ---------- | ----------------- |
| room     | references | foreign_key: true |
| user     | references | foreign_key: true |
 
 has_many: users 
 has_many: rooms



新しくテーブル、そのあとにカラムを追加後、EC２上に再度デプロイ。本番環境でチャットルーム新規作成ページにてルームを作成しようとすると、
<img src ='https://user-images.githubusercontent.com/58378273/95056184-4f496700-072f-11eb-9f67-3ebc5886198d.png'>
と表示されてしまった。

このエラーを解決するのに丸一日以上費やしたので、今後のためにも解決した方法をこの記事に載せることにしました。

やっかいだったのが、AWSの情報ってググってもまだ情報量が少ないので答えになかなか辿り着けませんでした。
そこで僕は、エラー解決でどうしようもないときたまにお世話になっている、MENTAを使うことにしました。

<h1>原因</h1>
EC2上で

```
tail -f production.log
```
でログを調べると

```
ActiveModel::UnknownAttributeError in RoomsController#create
unknown attribute 'name' for Room.
```
ログの中にこいつが見つかりました。前述しましたがこれが今回の原因です。

nameカラムがEC2上のデータベースにないですよ、という意味。


<h1>試したこと</h1>
まず、試したこととして、以下のコマンドで、Nginxの読み直しと再起動をしました。 

```
sudo systemctl reload nginx
sudo systemctl restart nginx
```

その後、以下のコマンドで、プロセスを確認。

````
ps aux | grep unicorn
````

```
kill プロセス番号
```
でプロセスをkillしました。

再度デプロイしてみます。

`````
bundle exec cap production deploy
`````


もう一度アクセスしてみましたが、変わりませんでした。
<img src ='https://user-images.githubusercontent.com/58378273/95056184-4f496700-072f-11eb-9f67-3ebc5886198d.png'>


前述しましたが、ググってもAWSの情報はまだ少ないので、解決方法になかなか辿り着けませんでした。

<h1>メンターからのアドバイス</h1>

そこで今回、MENTAでお願いをしたメンターより、以下のアドバイスをいただきました。

<b>「もし、nameカラムを追加したマイグレーションファイルが一番直近のものでかつロールバック可能であればロールバックして再度マイグレーションを適用するのがいいと思います。
一番簡単なのは一度データベースを作り直すことです。ただし、データが消えるのでデータが消えてもいい場合のみです。」

<b>「基本的にデータベースのロールバックというのはやらない方がいいです。
これをやっていいのは開発環境くらいで本番環境では常にマイグレーションファイルを追加する運用が最も安全かと思います。」 </b>

僕は、nameカラムはマイグレーションファイル作成後、必要だと気づいたので、
<b>①roomのマイグレーションファイルをrails db:rollbackでdownさせ
②downさせたマイグレーションファイルにnameカラムを追記
③再びrails db:migrate </b>

<b>→結果これが良くなかったことだったと判明 </b>

<h4>＝次回からは、カラム追加時は新しくマイグレーションファイルを別で作成するようにします!</h4>

<h1>解決方法手順</h1>
本場環境のデータベースを作り直すのであれば下記の方法で作り直せます。

````
DISABLE_DATABASE_ENVIRONMENT_CHECK=1 ./bin/rake db:drop
./bin/rake db:create
./bin/rake db:migrate
````

しかしコマンド実行後、以下のエラーメッセージが出力

````
エラー内容
FATAL: Listen error: unable to monitor directories for changes.
Visit https://github.com/guard/listen/wiki/Increasing-the-amount-of-inotify-watchers for info on how to fix this.
`````
ディレクトリの変更を監視することができませんという意味らしい…

<h1>エラーの原因</h1>
railsコンソールが起動できなかったのは、1つの実ユーザIDに対して生成できるinotifyのインスタンスの数の上限が決まっており、その上限に達してしまった為とのことです。
ここで、inotifyとはLinuxファイルやディレクトリのイベントを監視する機能です。

（参考URL: https://qiita.com/yn-misaki/items/c850a07f7858437e4d26）

```
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
```

再度試すも、

```
ターミナルで出たエラー内容

Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
Couldn't drop database 'original35700_development'
rake aborted!
Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
-e:1:in `<main>'
Tasks: TOP => db:drop:_unsafe
```
というエラーが表示

MySQLに繋げられていないようでした。

メンターから以下のコマンドを実行するよう指示。

```
RAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1 ./bin/rake db:drop
```

メンターから「既に削除できているっぽいので下記のコマンドを実行してください。」　とのこと

```
RAILS_ENV=production ./bin/rake db:create
RAILS_ENV=production ./bin/rake db:migrate
```

この2つのコマンドを実行し、再度EC2上にデプロイしたところ新たにEC２上でDBが反映され解決！

開発環境でテーブル作成後、あとからカラムを追加するときはrollbackではなく、addでマイグレーションファイルを新たに作成し追加するようにしましょう。