Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
29
Help us understand the problem. What is going on with this article?
@koolii

RailsでDBのレコードが”時々”なくなる!?

More than 5 years have passed since last update.

私が弊社に入る前からDBのレコードが全て消えるという現象が発生していて
今回私が原因っぽいところを発見して解決するまでの軌跡を。。。

※ 追記(ご注意)
この時の環境は複数ユーザー間でデータを共有したかったと言う
特殊な環境で発生した現象です。
基本はローカルに開発用DBとテスト用DBを建ててくださいね。

環境

  • Rails 4.1.8
  • Rspec 3.0.4(rspec-rails)

問題

単体テストを流すDBにデータ(レコード)が必要だったからです。
本当だったらFactoryGirl等で初期データを登録する等もあるんですが。。。

結論(先出し)

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!

この一行はRailsのバージョン4.1以降から対応しているもので

実行環境のDBと現在のマイグレーションの差分を検知し、
自動的にマイグレーションを掛けてくれるというものです。

この差分を検知し、自動的にマイグレーションをかける際に
DBを一度DROPしてからマイグレーションを流すため
DBの全レコードが無くなっていました。

解決

/config/environments/target.rb
  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)を別名にして実行してみた。(”時々”はどこに。。。)

案の定間違っていたので、実行環境毎の設定ファイルを眺めてみることに。


※ここで罠が...

config/environment/test.rb
# 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で単体テストを流す。

最後

そもそもテスト流す前にマイグレーション掛けようぜ!?

参考リンク
29
Help us understand the problem. What is going on with this article?
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
koolii
engineerlife
技術力をベースに人生を謳歌する人たちのコミュニティです。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
29
Help us understand the problem. What is going on with this article?