こんにちは。クライアントワーク事業部でサーバサイドエンジニアをやってる@kazasikiです。
今年もやってきましたAdvent Calendar。1日目は少し緊張しますね。
挨拶はほどほどにして、さっそくプログラムの話を始めましょう。
クライアントワーク事業部とRailsについて
エンジニアの方々であれば、Railsの紹介は不要かと思います。現在クライアントワーク事業部では多くのWebサイトをRailsで構築しています。比較的短い期間で小〜中規模のWebサイトを作り上げることが多く、品質と生産性を安定させる意味でも規約が多いWebフレームワークを使うのは理にかなった選択です。(少なくとも私はそう思ってます。)
しかし、規約が多いRailsの中でも、人によって違う使い方をしてしまう機能がいろいろとあります。今回はその一つとしてrails db:seed
やその周辺を取り挙げます。
Railsのデータファイルに対する考え方
まず、Railsにはデータを記述するファイルとして
db/seeds.rb
test/fixtures/*
の2つがあります。
db/seeds.rb
はその名の通り、シードデータを記述するファイルです。rails db:seed
を実行すると読み込まれて実行されます。
test/fixtures/*
はrails test
でminitestを実行する際に使用されるデータです。
この2つのうち、特にdb/seeds.rb
について個々人で認識がズレることが有ります。ざっくりいうと、
- アプリケーション動作に必須な所謂マスタテーブルのデータ
- 開発環境などに使う動作確認用のデータ(とりあえず全テーブルに5件ぐらい入れとくやつ)
のどちらを書くファイルなのかという点です。
解決策としては環境ごとに投入する初期データを変えるのような方法が簡単でしょう。
しかし、Railsは「動作確認用のデータ」を入れるファイルを決めていないのでしょうか?そうではありません。
Railsはそういったデータを入れるファイルをtest/fixtures/*
とした上で、rails db:fixtures:load
を提供しています。
rails db:fixtures:load を使う
test/fixtures/*
はrails test
のためのデータを記述するファイルというイメージが強いですが、テストをちゃんと書いているのであれば動作確認に必要なデータは一通り揃っている筈です。
rails db:fixtures:load
はtest/fixtures/*
のデータをrails test
のときと同じやり方でdevelopment用のDBに投入してくれます。
これは以下のような分かりやすい住み分けを提供してくれます。
db/seeds.rb
はアプリケーション動作に必須なデータを記述するファイルtest/fixtures/*
は動作確認用のデータを入れるファイル
開発環境ではrails db:create db:migrate db:seed
を基本的には実行しつつ、程よいデータがほしければ適宜rails db:fixtures:load
を実行すればよいということです。
rails db:fixtures:load で困ること
とはいえ、rails db:fixtures:load
を使わない正当な理由も沢山あります。
- そもそもあんまりテストを書いてないから
test/fixtures/*
が充実してない - 標準のfixturesではなく、factory_girlなどのgemを使っている。
- yml(+erb)はテストデータのバリエーションの作り込みがやりにくい
3番目のやつはRailsGuideにあるような以下のような書き方がyml(erb)だと少しやり難いという話です。
# db/seeds.rb 5.times do |i| Product.create(name: "Product ##{i}", description: "A product.") end
# test/fixtures/products.yml <% 5.times do |i| %> product_<%= i %>: name: <%= "Product ##{i}" %> description: A product. <% end %>
まとめ
以上、Railsプロジェクト内でのデータファイルの住み分けの話でした。
rails db:fixtures:load
をうまく使ってる人が少ない気がしたので書きました。
明日は、@KAMEDAkyosuke さんがiOSに追加された話題の機能について書いてくれるらしいです。お楽しみに!