db/schema.rbは何に使われるのか
rake db:migrateなどをすると現在のスキーマが反映され、スキーマの確認などに便利なschema.rb。
ふと、1つのRailsアプリを分割して、複数のRailsアプリから同じDBを参照するようにしたくなったのだが、その際にどちらのRailsアプリにもdb/schema.rbを含める必要があるのか気になった。
db/schema.rbを削除してもアプリは動くのだが、
schema.rbには「It's strongly recommended that you check this file into your version control system.」と書いてあるので、本当に削除していいのか自信がない。
そこで、Rails4.1.5のソースを読んで、schema.rbがどんな用途に使われているのかを調査した。
schema.rbが使われている3箇所
rails/railsのファイル全てに対してschema.rbでgrepをかけると、3箇所で使われていることがわかる。
- ActiveRecord::Railtieのinitializer
- ActiveRecord::Tasks::DatabaseTasks
- active_record/railties/databases.rake
それぞれが最終的にどのような役割を果たすか説明する。
1. ActiveRecord::Railtieのinitializer
ActiveRecord::Railtie
内に定義されているinitializerで、config.watchable_files
にdb/schema.rbを追加している。
読み進めていくと、watchable_filesはこのへんで使われていて、watchable_filesが更新されたときに、読み込んだ依存関係をクリアするようになっている。
つまり、schema.rbがあると、そのアプリでスキーマを更新した後、依存関係の再読み込みが行われるようになる。
別のアプリ等でスキーマ管理をする場合は、スキーマが更新されたらこの仕組みを使う(rake db:schema:load等)か何らかの方法で読み込んだ依存関係をクリアする必要がある。
2. ActiveRecord::Tasks::DatabaseTasks
これは実際のところ3でのみ使われるモジュールである。
3がdb/schema.rbを読み込むときに使われる。
3. active_record/railties/databases.rake
rake db:** のタスクが定義されているファイル。
この中で、schema.rbを使うタスクは以下のとおりであった。 (deprecatedなものを除く)
-
rake db:schema:dump
- db:migrate、db:rollback などが依存している
- 現在のスキーマからschema.rbを作成する
-
rake db:schema:load
- db:setup、db:reset などが依存している
- schema.rbからテーブルを作成する
要するにschema.rbにスキーマ定義をダンプしたり、schema.rbからダンプしておいたスキーマを再現するのに使える。
試しでインデックスを張り替えたりしていると本来のスキーマとずれてしまうことがあると思うが、その際にschema.rbがあれば元の状態に復元できるので、複数の環境間でスキーマの整合性を保つためにschema.rbは1つはあったほうが良い。
逆に、1つschema.rbがどこかで管理されていれば、同じDBを使う他のrailsアプリではschema.rbは配置しなくて良いと言える。
まとめ
db/schema.rbはなくても動くが、複数の環境間でスキーマの整合性を保つためにどこかに1つは管理しておくべきである。