Help us understand the problem. What is going on with this article?

【Rails】we're sorry, but something went wrongでハマった話(2)

こんにちは!スージーです!
ローカル環境では問題なかったのに本番環境で発生したwe're sorry, but something went wrongの解決までを備忘録として

we're sorry, but something went wrong

このエラーは本番環境でちょいちょい見るのでproduction.logでエラーログを確認する

ターミナル
[ec2-user@ip-~~]$ cd /var/www/app-name
[ec2-user@ip-~~]$ cd log
[ec2-user@ip-~~]$ cat production.log
D, [2019-11-18T07:06:44.834244 #5661] DEBUG -- : hogehoge~~
D, [2019-11-18T07:06:44.834597 #5661] DEBUG -- : hogehoge~~
・
・・
・・・

この時はproduction.logにエラーログが無かった

デバックを考える

  • タイポ→× 開発環境でもエラーが再現されているはず
  • no method error→× 開発環境でもエラーが再現されているはず
  • ルーティングアクション,コントローラの記述がおかしい→× 開発環境でもエラーが再現されているはず
  • エラー発生ページshowアクション:idが本番環境にないのではないか?(同期が教えてくれた)

本番環境のMySQLにログインしてみる

同期の助言により、以前に本番環境下でseedファイルのデータが投入できなかった事を思い出す

ターミナル
[ec2-user@ip-~app-name]$  mysql -u root -p
Enter password:
・
・・
mysql > use app-name_production;
・
・・
database changed
mysql > describe meals;
# <エラーが発生するテーブル>
mysql > show * form meals;
# <レコードを確認>

mealsテーブル

Column Type Options
name varchar null: false
image text
food_stuff text
cooking_time integer null: false
cooking_method integer
post_id integer null: false
user_id integer null: false

エラー箇所特定

user_id:1で投稿したはずなのにmealsテーブルuser_idカラムにはuser_id:17で保存されている...
開発環境では問題なくuser_idが保存されているから道理でエラーが再現されないはずだ...

原因

このuser_idはデプロイ後に追加したカラム
開発環境でマイグレーションファイルを作成した後に以下の手順でdb:migrateした

ターミナル
[ec2-user@ip-~app-name]$ RAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rake db:drop
#<最新のDBにする為,一度drop>
[ec2-user@ip-~app-name]$ rake db:create RAILS_ENV=production
#<DBをcreateする>
[ec2-user@ip-~app-name]$ rake db:migrate RAILS_ENV=production
#<migrateする>
[ec2-user@ip-~app-name]$ cd current
#<currentディレクトリ下へ>
[ec2-user@ip-~app-name]$ rake db:seed RAILS_ENV=production
・
・・
・・・
Mysql2::Error: Field 'user_id' doesn't have a default value

上記エラーが最初出た時にuser_idカラムをMySQLにログインしてカラムを新規で作成し突っ込んでいた

ターミナル
database changed
mysql > ALTER TABLE meals ADD user_id int;
mysql > exit
[ec2-user@ip-~app-name]$ cd current
[ec2-user@ip-~app-name]$ rake db:seed RAILS_ENV=production
・
・・
・・・
Mysql2::Error: Field 'user_id' doesn't have a default value

またエラーが出ている...アプリを動かして投稿してみると新規投稿はできていたので、その時は一旦保留にしていたが、やはりここが今回のエラーの原因であるのは間違いなさそう

解決方法

なぜ最新のマイグレーションファイルが本番環境に反映されないのか

参考
【Rails】本番環境デプロイでよく使うコマンド集!AWS/unicorn/nginx/Capistrano使用
https://qiita.com/15grmr/items/7ad36caa82a0fa27c4bd

むむむ...db:migrateの手順が間違っていた...無理矢理に本番環境のDB構造を変えて正しくuser_idが保存されていないのが原因であれば正しくマイグレーションすればエラーは解決するはず。そうすればdb:seedでデータが投入されるはずである

ターミナル
[ec2-user@ip-~app-name]$ RAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rake db:drop
[ec2-user@ip-~app-name]$ rake db:create RAILS_ENV=production
# ここで一度自動デプロイをかけて、db:migrateに当たる操作を完了
# ローカルにて
app-name $ bundle exec cap production deploy
# 無事作成されたら、再度EC2のcurrentディレクトリでseedを反映させる
[ec2-user@ip-~app-name current]$ rake db:seed RAILS_ENV=production
・
・・
・・・
[ec2-user@ip-~app-name current]$

無事にseedファイルが本番環境に投下されwe're sorry, but something went wrongのエラーは解決

まとめ

今回、個人アプリで初めてデプロイ後のDB構造を変更・追加を行った。EC2内でdb:create→db:migrateまでしてから自動デプロイしても最新のマイグレーションファイルが本番環境へ反映されない事が原因だった。EC2内では古いDBをdropcreateする所までを行い、capistranoを使った自動デプロイで最新マイグレーションをファイルの読み込みmigrateする

今回のエラーはデプロイの手順の間違えで発生したものだったが、MySQLを触っているとRailsではマイグレーションファイルでバージョン管理してくれるし、ORMのお陰で生SQLを触る機会もほとんどないのでDB関連の知識が無くても動くアプリケーションが作れる。非常に便利だが、SQLの勉強は絶対にした方が良いと感じたエラーだった

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away