開発中のエラーでよく出てくるActiveRecord::PendingMigrationErrorについて調べてみました。Railsのバージョンは5.1.5です。

開発環境のエラー画面でPendingMigrationErrorが発生するのは以下の設定がされていることが条件です。

ActiveRecord::RailtieのinitializerでRackミドルウェアにActiveRecord::Migration::CheckPendingを設定します。

ActiveRecord::Migration::CheckPending#callはActiveRecord::Migration.check_pending!を呼び出します。

check_pending!はActiveRecord::Migrator.needs_migration?を呼び出し、trueのときにActiveRecord::PendingMigrationErrorをraiseします。

needs_migration?ではdb/migratesディレクトリ内のマイグレーションファイル名から正規表現でバージョンを取得し、実際にマイグレーションしたバージョンが入るschema_migrationsのレコードと比較し、マイグレーションしていないファイルが存在すればtrueを返します。

get_all_versionsはActiveRecord::SchemaMigration.all_versionsを呼び出します。schema_migrations_table_nameはschema_migrationsに設定されているため、ActiveRecord::SchemaMigrationはテーブル名がschema_migrationsのActiveRecordとして振る舞います。

まとめると、Rackミドルウェアを使ってマイグレーションファイルとDB内のマイグレーション情報を比較してActiveRecord::PendingMigrationErrorを出しています。