私が弊社に入る前からDBのレコードが全て消えるという現象が発生していて
今回私が原因っぽいところを発見して解決するまでの軌跡を。。。
※ 追記(ご注意)
この時の環境は複数ユーザー間でデータを共有したかったと言う
特殊な環境で発生した現象です。
基本はローカルに開発用DBとテスト用DBを建ててくださいね。
環境
- Rails 4.1.8
- Rspec 3.0.4(rspec-rails)
問題
単体テストを流すDBにデータ(レコード)が必要だったからです。
本当だったらFactoryGirl等で初期データを登録する等もあるんですが。。。
結論(先出し)
# Checks for pending migrations before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.maintain_test_schema!
この一行はRailsのバージョン4.1以降から対応しているもので
実行環境のDBと現在のマイグレーションの差分を検知し、
自動的にマイグレーションを掛けてくれるというものです。
この差分を検知し、自動的にマイグレーションをかける際に
DBを一度DROPしてからマイグレーションを流すため
DBの全レコードが無くなっていました。
解決
config.active_record.maintain_test_schema = false
を付加することで、差分を検知したとしても
そのままフローが進むように設定することが出来ます。
つまりデータ(レコード)は残る!!
※ 設定内容に関しては下のリンクから確認できます。
発見まで
上記のように弊社に入社してから度々DBの全レコードが無くなる現象が発生していた。
私は最近バックエンドの修正でRailsプロジェクトの開発を行っていて、
なぜか私が単体テストを流す度にDBの全データが無くなっていた。
この辺りで、当Railsプロジェクト。
さらに言えば、マイグレーション周辺がおかしいんだろうと言うアタリをつけて
持っていたタスクそっちのけで調査していた。
Rails初心者なのでRailsが悪いのか、Rspecが悪いのか、ActiveRecordが悪いのか
調査するのには時間が掛かりました(汗
まずは実行環境に目を付けました。
原因1(?) 実行環境(test)自体
Railsには3つの実行環境が標準で存在しています。
- production -本番環境
- test -テスト機
- development -開発機
私は、Railsは規約を重んじていたよね?ということで
testの実行環境は問答無用でテスト開始前に全レコードを削除しているのでは?と言う事で
実行環境(test)を別名にして実行してみた。(”時々”はどこに。。。)
案の定間違っていたので、実行環境毎の設定ファイルを眺めてみることに。
※ここで罠が...
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
config.cache_classes = true
私の英語力に問題があったと思いますが、
config.cache_classes = true
であればDBがリセットされると勘違いしてしまいました。
実際は上記の結論なので。
原因2(?) 実行環境の設定
該当する実行環境以外では全レコードが無くなる現象は起きなかったため
他の実行環境をコピーした。
だが、ここでも意味はなかった。
次に、そもそもとしてどのようなSQLが流れているのかちゃんと確認しようということでログ・ファイルを確認した。
ログはroot直下のlogディレクトリに実行環境毎にあった。
中を見ると、
DROP DATABASE IF EXISTS `database_name`
DROPが。。。流れてる!!?
DROPが流れているということでRspec関連ファイルの
- spec_helper.rb
- rails_helper.rb
を見てみることに。
ここから順繰り中身を見ていって結論に記載している
# Checks for pending migrations before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.maintain_test_schema!
が問題だと判明しました。
使用したコマンド達
1$ RAILS_ENV=test bundle exec rake db:migrate
2$ bundle exec rspec path_to_file.rb
-
1$
実行環境を指定(test)し、マイグレーションを行う。 -
2$
Rspecで単体テストを流す。
最後
そもそもテスト流す前にマイグレーション掛けようぜ!?