💭

デプロイ時のエラー(bigint 🆚 integer)

2023/06/23に公開

はじめに

ポートフォリオ作成中のプログラミング初学者です🔰
今日はテストデプロイに苦労しましたが、無事完了いたしました!

デプロイ時のエラー

デプロイ後、以下のようなブラウザ画面が表示されました!
この場合はRailsアプリケーションのエラーである可能性が高いようです。

Railsのエラーログを確認する方法

本番環境で起動したRails側のログは、log/production.logに蓄積されていきます。
tailコマンドに-fオプションを使用することでリアルタイムに監視することができます。

$ sudo tail -f log/production.log

エラーログのみ出力する
以下のコマンドを入力すると、対象ファイルのERROR部分の最後をリアルタイムで表示してくれます。

$ tail -f ファイルパス | grep ERROR

今回のエラー

今回の場合は、Railsアプリケーションをデプロイする際の下記コマンドで
テーブルについてのエラーが出ました。

[ec2-user@ip-xx-xx-xx-xx GitHubのリポジトリ名]$ bundle exec rails assets:precompile RAILS_ENV=production

migrationし直そうとしたところ、下記のようなエラーが。

Column `end_user_id` on table `workout_likes` does not match column `id` on `end_users`,
which has type `bigint(20)`.
To resolve this issue, change the type of the `end_user_id`column on `workout_likes` to be :bigint.
(For example `t.bigint :end_user_id`).
Original message: Mysql2::Error: Cannot add foreign key constraint

原因

結論、referencesで作っていた外部キーにtype: :integer型を指定しまっていたことが原因でした。type指定しなければデフォルトでbigintになるのに余計なことしてた😂

誤)
t.references :end_user, type: :integer, null: false, foreign_key: true

Rails 5.1以降では、新たに生成されるマイグレーションファイルのidおよびreferences/belongs_toカラムのデフォルト型はbigintとなっています。(大規模なアプリケーションではinteger型の範囲(約21億)を超える可能性があるため、より大きな範囲を持つbigint型がデフォルトとなりました。)

そのため、あるテーブルのidカラムがbigint型で、それを参照する外部キーがinteger型であると、型の不一致から外部キー制約の追加に失敗するという問題が発生します。

bigintなんて言葉を初めて聞いたので戸惑いましたが、
全てのinteger型のIDに下記のように type: :bigintを付け足すことでエラーが解消されました!!😂

正)
t.references :end_user, type: :bigint, null: false, foreign_key: true

SQLiteとMySQL

学習では、標準データベース(SQLite)を使ってアプリケーションを作成
🔽
今回のデプロイでより頑丈で安定性に優れた「MySQL」を利用

調べたところ、、
SQLiteとMySQLは、データ型と外部キー制約の取り扱いに違いがあるようで、、

  • SQLiteは型付けの柔軟性があり、たとえば整数型の列に対して文字列を挿入することも可能です。したがって、SQLiteではINTEGER型とBIGINT型の間に明確な区別はありません。そのため、SQLiteでは型の不一致によるエラーは起こらない可能性が高いです。

  • 一方、MySQLはより厳密な型付けを行います。そのため、外部キーとして設定された列のデータ型が、参照先の主キーのデータ型と一致しない場合、外部キー制約のエラーが発生します。

したがって、RailsのマイグレーションがSQLiteでは問題なく動作していたのに、MySQLではエラーが発生したという状況は、MySQLの厳密な型付けが原因である可能性があります。

とのこと。なるほど〜💡

エラー分にずっとend_user部分がおかしいと出ていたので、メンターさんはその部分しか見ておらず、他の外部キーは直さないまま2〜3時間沼にハマってました、、😇
最終的にはやっぱそこだったかい!って感じでしたが、メンターさんも諦めかけてたので無事解決できて泣きそうになりました😂

migrationファイルの作成順

また、migrationファイルの作成順でもエラーがちらほら出ていたので注意です!
migrationファイルの名前の作成日時部分を手動でいじって並び替えして解決しました!

中間テーブルを作成する際には、参照するテーブル(親テーブル)が存在している必要があります。参照するテーブルがない場合、中間テーブルの外部キー制約を設定することができません!

具体的な手順としては、次のような順序でテーブルを作成することが一般的です💪🏻

  1. 参照するテーブル(親テーブル)を作成する。
  2. 中間テーブルを作成する。
  3. 中間テーブルに外部キー制約を追加する。
  4. 中間テーブルの関連するテーブルへの外部キーを設定する。

さいごに

MySQLは結構厳格なのだな、ということがわかりました。
開発環境で問題がなくても本番環境でこのようにエラーが結構出ました。
全然コマンドの意味を理解できてないままですが、
関係性についてはまた再度見直して理解しようと思ってます!👀

今日はここまで!🌛

参考にさせていただいた記事🌱

https://qiita.com/Jwataru/items/7b840be38d4279224245

Discussion