内容
Ruby on Railsで開発をするときに、開発用のデータ (シードデータ)があると便利で、これがないとあるとでは開発速度が違うと思います
FactoryGirlはテスト用データを作る際によく利用されるかと思いますが、これを開発用データを構築する際に使うと便利なので紹介します
※ 慣れた開発者は既知だと思うので、この記事をすっ飛ばしてください
開発環境
- Ruby:
2.4.0
- Rails:
5.0.1
- FactoryGirl:
4.8.0
- FactoryGirlRails:
4.8.0
Model
今回はbooksというテーブルがあったとします
# == Schema Information
#
# Table name: books
#
# id :integer not null, primary key
# title :string(255) not null
# created_at :datetime
# updated_at :datetime
#
class Book < ApplicationRecord
end
※ 上の様にスキーマをmodelに書いてくれるannotate
というgemが便利です
FactoryGirl
FactoryGirlは以下に設定します。
# == Schema Information
#
# Table name: books
#
# id :integer not null, primary key
# title :string(255) not null
# created_at :datetime
# updated_at :datetime
#
FactoryGirl.define do
factory :book do
sequence(:title) { |n| "Book Title#{n}" }
end
end
annotate
を入れておくと、ここにもスキーマの情報を書いてくれるので便利です
筆者はRspecを使っています
Seed
本題、シードデータを用意します
require 'factory_girl'
include FactoryGirl::Syntax::Methods
FactoryGirl.definition_file_paths = [ Rails.root.join('spec', 'factories') ]
FactoryGirl.reload
table_names = %w(
books
)
table_names.each do |table_name|
path = Rails.root.join("db/seeds", Rails.env, table_name + ".rb")
if File.exist?(path)
puts "Creating #{table_name}..."
require path
end
end
ここでは、FactoryGirlをrequire
して、ファイルの場所はspec/factories
にあることを設定しています
さらに、シードデータを入れる際に実装するファイルをtables
にいれ、読み込みます
5.times{ create(:book) }
ここを言いたかったのですが、このcreate(:book)
がFactoryGirlが提供しているメソッドです
bin/rails db:seed
これでFactoryGirlを利用してシードデータを投入することができした
何がいいのか
db/seeds/development/books.rb
は以下の様に書くこともできます
5.times{ |n|
Book.create({
title: "Book Title#{n}"
})
}
ならこれでいいじゃんという話になるのですが、開発を進めていくと、このbooks
のテーブルをいじりたいという要望が高確率で出てきます
その際に、カラムを変更したり、null制約を変更したりすると、それに応じてシードデータやテストにも変更を加える必要が生じます
大規模かつ重要なテーブルでは変更漏れなど、ケアレスミスは避けたいところです
そのため、シードデータ、テストデータを用意するための記述は限りなく少ない方がいいはずです
これは筆者の主観ですが、一個変えたら全部変わる様な設計がいいなと思います