何がうれしいか
- seedデータの一部を変更した時、変更したファイルだけを読み込み、データの更新や追加ができる
- デフォルトの
seeds.rb
の場合、既存のデータを削除してから再度読み込まなきゃいけない
- デフォルトの
- 環境ごとにseedデータを分けやすくなる
インストール
Gemfile
gem 'seed-fu'
$ bundle install
$ mkdir db/fixtures # 必須
# 以下、環境ごとにseedファイルを分けたい場合に作成
$ mkdir db/fixtures/development
$ mkdir db/fixtures/production
データを読み込む
$ touch db/fixtures/development/01_user.rb #ファイル名は自由。アルファベット順に読み込まれる。
以下の2通りの書き方がある。データが多い時は2つ目の書き方の方が良さそう。
基本の書き方
User.seed do |s|
s.id = 1
s.name = '茂野吾郎'
s.email = 'shigeno@example.com'
s.password = 'password'
end
User.seed do |s|
s.id = 2
s.name = '佐藤寿也'
s.email = 'sato@example.com'
s.password = 'password'
end
この書き方でも良い
User.seed(
{
name: '茂野吾郎',
email: 'shigeno@example.com',
password: 'password'
},
{
name: '佐藤寿也',
email: 'sato@example.com',
password: 'password'
},
)
$ rails db:seed_fu
読み込むseedファイルを明示的に指定する
$ rails db:seed_fu
開発環境で上記のコマンドを叩くと、db/fixtures/development
以下のファイルだけが読み込まれる。
他のディレクトリのファイルを読みたい場合などには以下のようにディレクトリを指定することができる。
$ rails db:seed_fu FIXTURE_PATH=db/fixtures/hogehoge
【注意】データの同一性はidで判断される
既存のデータが更新されたのか、新規データが追加されたのかは、idを元に判断されている。seedファイル内のデータにidを書かないと、既存のデータを更新したつもりでも新規データが追加されてしまう。
id以外の(ユニークな)データを基準にデータの同一性を判断させたい場合は、以下のように書く。
emailがユニークな場合
User.seed(:email) do |s|
s.name = 'foo'
s.email = 'foo@example.com'
s.password = 'password'
end
# or
User.seed(:email,
{
name: 'foo',
email: 'foo@example.com',
password: 'password'
}
)
既存のDBからseedファイルを作成するrakeタスク
SeedFu::Writer.write
を使ってseedファイルを作ることができる
$ rails g task seed-fu-gen-user
lib.tasks/seed_fu_gen_user.rake
namespace :seed_fu_gen_user do
desc 'usersテーブルのデータを元にseedファイルを生成'
task create_seed_by_db: :environment do
SeedFu::Writer.write('./db/fixtures/user_gen.rb', class_name: 'User') do |w|
User.all.each do |x|
w << x.as_json(except: %i[created_at updated_at])
end
end
end
end
$ ./bin/rake seed_fu_gen_user:create_seed_by_db
※公式のREADMEを読むと、SeedFu::Writer
にはもろもろ変更が入ったと注意書きがありますが、少なくともver2.3.9では上記の方法で動作確認ができました。