Edited at

Railsの開発用データを用意する際に、FactoryGirlが便利だったりする

More than 1 year has passed since last update.


内容

Ruby on Railsで開発をするときに、開発用のデータ (シードデータ)があると便利で、これがないとあるとでは開発速度が違うと思います

FactoryGirlはテスト用データを作る際によく利用されるかと思いますが、これを開発用データを構築する際に使うと便利なので紹介します

※ 慣れた開発者は既知だと思うので、この記事をすっ飛ばしてください


開発環境


  • Ruby: 2.4.0

  • Rails: 5.0.1

  • FactoryGirl: 4.8.0

  • FactoryGirlRails: 4.8.0


Model

今回はbooksというテーブルがあったとします


app/models/book.rb

# == 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は以下に設定します。


spec/factories/books.rb

# == 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

本題、シードデータを用意します


db/seeds.rb

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にいれ、読み込みます


db/seeds/development/books.rb

5.times{ create(:book) }


ここを言いたかったのですが、このcreate(:book)がFactoryGirlが提供しているメソッドです

bin/rails db:seed

これでFactoryGirlを利用してシードデータを投入することができした


何がいいのか

db/seeds/development/books.rbは以下の様に書くこともできます


db/seeds/development/books.rb

5.times{ |n|

Book.create({
title: "Book Title#{n}"
})
}

ならこれでいいじゃんという話になるのですが、開発を進めていくと、このbooksのテーブルをいじりたいという要望が高確率で出てきます

その際に、カラムを変更したり、null制約を変更したりすると、それに応じてシードデータやテストにも変更を加える必要が生じます

大規模かつ重要なテーブルでは変更漏れなど、ケアレスミスは避けたいところです

そのため、シードデータ、テストデータを用意するための記述は限りなく少ない方がいいはずです

これは筆者の主観ですが、一個変えたら全部変わる様な設計がいいなと思います