【1】はじめに
記事を作成した経緯
私は4月に進学した大学の課外活動で初めてプログラミング言語について学び始め、 Railsを使ってチーム開発をおこなっている。そこで多くのエラーを吐かれいろいろなサイトを参考にしてみたものの、根本的な解決方法を見つけることができなかったため、ここにまとめる。
また、内容の一部を関連記事を基に記載している。
目的
Railsに関するエラーや対処方法について、自分と同じような悩みを持つ人が読みやすい資料として一括にまとめる。また、各章末に、参考にした記事などのURLを貼っておくので活用してほしい。
お願い
本記事内では、私が「詰まった」あるいは「必要」だと感じた内容を記載しており、内容の一部は「項4.参考サイト」にある記事を参考にしている。また、本記事内に記載のない内容についても同じくリンクしてあるので、もし不明なことがあれば参考先を確認することで解決できる場合がある。
【2】本記事のエラー内容の種類
エラー1
実行内容
次のようにモデルを作成した。
myapp# rails g model User name:string schoolnumber:integer grade:integer
invoke active_record
create db/migrate/20240925141211_create_users.rb
create app/models/user.rb
一見、成功しているようにみえるが、対象ファイルをマイグレートしようと、 rails db:migrate
を実行しようとしたが、すでに対象ファイルを削除してしまっていた。ひとつ前に戻そうと rails rollback
をすると以下のエラーが出た。
--実行コマンド--
myapp# rails db:rollback
--エラー内容--
bin/rails aborted!
ActiveRecord::UnknownMigrationVersionError: (ActiveRecord::UnknownMigrationVersionError)
No migration with version number 20240924023519.
エラー内容
このエラーメッセージ ActiveRecord::UnknownMigrationVersionError
は、指定されたバージョン番号 (20240924023519) のマイグレーションが存在しないことを示している。db:rollback
を実行しようとした際に、このバージョンのマイグレーションがデータベースにはないため、エラーが発生している。
予想される原因
1.削除されたマイグレーション
そのマイグレーションファイルが存在していない、あるいは手動で削除された可能性がある。
2.マイグレーションのファイル名の変更
ファイル名が手動で変更されたか、不完全な状態で存在している可能性がある。
解決策
1. db/schema.rb
の確認
まず、db/schema.rb
ファイルを確認して、問題のマイグレーションが適用されているかどうかをチェックし、version フィールドに該当するバージョン番号がない場合、それはまだ適用されていないことを意味する。
2.マイグレーションファイルの確認
db/migrate
ディレクトリに移動し、20240924023519
のマイグレーションファイルが存在するかどうかの確認を行う必要がある。
$ ls db/migrate
このバージョン番号に一致するファイルがない場合、それが原因である。
3.マイグレーションバージョンを手動で修正
- 該当バージョンのマイグレーションがすでに削除されていて実行できない場合、手動でデータベースのバージョン情報を修正することができる
- データベースの schema_migrations テーブルに該当バージョンが存在していれば、手動で削除することもできる(ただし、慎重に行う必要がある)
コマンド例(該当バージョンが存在する場合に手動で削除)
番号の順番に行う。
①コンソールに入る
myapp# rails console
②手動で削除
> DELETE FROM schema_migrations WHERE version = '20240924023519';
4.強制的にリセット
最後の手段として、データベースをリセットし、すべてのマイグレーションを再実行することが可能である。
myapp# rails db:drop db:create db:migrate
これによってデータベースが初期化され、すべてのマイグレーションが再度適用される。
エラー2
実行内容
myapp# rails g model User name:string schoolnumber:integer grade:integer
invoke active_record
The name 'User' is either already used in your application or reserved by Ruby on Rails. Please choose an alternative or use --skip-collision-check or --force to skip this check and run this generator again.
エラー内容
User
という名前のモデル名が既に存在しているか、Rails で予約されている名前(予約語)のため、新しくモデルを生成しようとした際に衝突している。
解決方法(いくつかの選択肢あり)
1.モデルの名前を変更
既存の User
モデルがある場合、別の名前を使って新しいモデルを作成することができる。例えば、Account
や Member
のような名前を使うことが考えらる。
rails g model Account name:string schoolnumber:integer grade:integer
2.既存の User
モデルを裁量する
もし、User
モデルがすでに存在しており、それが再利用可能であれば、rails g model
コマンドを実行する必要がなく、既存のモデルを修正し、必要なフィールド(name
, schoolnumber
, grade
)を追加することができる。
- マイグレーションを追加して、
User
テーブルにフィールドを追加する
rails g migration AddDetailsToUsers name:string schoolnumber:integer grade:integer
- その後、マイグレーションを実行
rails db:migrate
**3.--force
オプションを使用して上書きする
もし、古い User
モデルを削除したい、もしくは完全に新しくしたい場合は、--force
オプションを使って既存の衝突を無視し、新しい User
モデルを上書きすることができる。
rails g model User name:string schoolnumber:integer grade:integer --force
--force
オプションを使用する場合、既存の User
モデルやマイグレーションが上書きされる可能性があるため、慎重に行う必要がある。
4.衝突をスキップする
衝突チェックをスキップして実行したい場合は、--skip-collision-check
を使うことも可能である。ただし、この方法では、既存のファイルが保持される可能性があるため注意が必要である。
rails g model User name:string schoolnumber:integer grade:integer --skip-collision-check
エラー3
このエラーは、エラー2
のときに出たエラーである。
実行内容
myapp# rails g migration AddDetailsToUsers name:string schoolnumber:integer grade:integer
invoke active_record
create db/migrate/20240925142629_add_details_to_users.rb
root@dfbd85317b40:/myapp# rails db:migrate
== 20240925142629 AddDetailsToUsers: migrating ================================
-- add_column(:users, :name, :string)
bin/rails aborted!
StandardError: An error has occurred, all later migrations canceled: (StandardError)
Mysql2::Error: Duplicate column name 'name'
/myapp/db/migrate/20240925142629_add_details_to_users.rb:3:in change'
Caused by:
ActiveRecord::StatementInvalid: Mysql2::Error: Duplicate column name 'name' (ActiveRecord::StatementInvalid)
/myapp/db/migrate/20240925142629_add_details_to_users.rb:3:in change'
Caused by:
Mysql2::Error: Duplicate column name 'name' (Mysql2::Error)
/myapp/db/migrate/20240925142629_add_details_to_users.rb:3:in change'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
エラー内容
このエラーメッセージは、データベースの users
テーブルに既に name
というカラムが存在しているため、マイグレーションで同じカラムを追加しようとしてエラーが発生していることを示している。