Just do IT

思うは招く

seed-fu gem を使ってみる

seed-fu という gem に触る機会があったため、どんなものかサンプルを動かしてみた。

seed-fu とは

mbleigh/seed-fu: Advanced seed data handling for Rails, combining the best practices of several methods together.

  • Rails デフォルトのseed機能だと、db:seedするたびに同じデータが生成される
  • seed-fu はよしなにデータを生成してくれる
    • 追加や修正がしやすい

僕は自分で触ってみないとあまり理解できないタイプなので、小さいサンプルを作って動かしてみた。

なお、もふもふさんの以下記事を参考にしている。

seed-fuを使って開発・テスト・本番それぞれの環境でのシードデータを作成する | もふもふ技術部

手順

プロダクションでも使うので環境は指定しない。

gem 'seed-fu'

モデル作成1

$ rails g model Customer name email

モデル作成2

$ rails g model Address  prefecture city customer:references

マイグレーション

$ bin/rails db:migrate

※DBはデフォルトのSQLite3を使用

紐付け

class Customer < ApplicationRecord
  has_many :addresses, dependent: :destroy
end
class Address < ApplicationRecord
  belongs_to :customer
end

fixturesのディレクトリ作成

$ mkdir db/fixtures/development

ここにseedデータのファイルを作成していく。今回はdevelopmentだけだが、productionなどでも作れる。

fixuture ファイルを作成

$ touch db/fixtures/01_cutomers.rb
$ touch db/fixtures/02_addresses.rb

seed-fu のファイルは上記のように命名すると、順番を指定してseedデータ作成ができる。今回の場合、カスタマーを先に作らないといけないため、01とプレフィックスをつけている。

db/fixtures/01_cutomers.rb

Customer.seed do |s|
  s.id = 1
  s.name = 'テストユーザー'
  s.email = 'sample@example.com'
end

db/fixtures/02_addresses.rb

Address.seed do |s|
  s.id = 1
  s.prefecture = 'Tokyo'
  s.city = 'Shibuya'
  s.customer_id = 1
end

データ投入

$ bin/rails db:seed_fu

データ確認

$ rails c
irb(main):001:0> Customer.all
   (0.4ms)  SELECT sqlite_version(*)
  Customer Load (0.1ms)  SELECT "customers".* FROM "customers" LIMIT ?  [["LIMIT", 11]]
=> #<ActiveRecord::Relation [#<Customer id: 1, name: "テストユーザー", email: "sample@example.com", created_at: "2020-12-15 11:37:56", updated_at: "2020-12-15 11:37:56">]>

まずカスタマーのデータはできている様子。

irb(main):002:0> c = Customer.find 1
  Customer Load (0.3ms)  SELECT "customers".* FROM "customers" WHERE "customers"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]

カスタマーのデータを c という変数にいれて

irb(main):004:0> c.addresses
  Address Load (0.1ms)  SELECT "addresses".* FROM "addresses" WHERE "addresses"."customer_id" = ? LIMIT ?  [["customer_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Address id: 1, prefecture: "Tokyo", city: "Shibuya", customer_id: 1, created_at: "2020-12-15 11:37:56", updated_at: "2020-12-15 11:37:56">]>

アドレスも紐付けされてデータが生成されていますね。

余談

便利なgemなんだけど、記事執筆時点で seed-fu の最後のコミットは Apr 7, 2018 なのがとても気になる・・・😅

参考

seed-fuを使って開発・テスト・本番それぞれの環境でのシードデータを作成する | もふもふ技術部