4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Seed Fu の API を使用する際の Tips

Posted at

Seed Fu の rake タスクではなく、API を使用する際のアレコレです。

Seed Fu の インストールや基本的な使用方法

公式ドキュメントを参照。

Tip1: rake db:seed された場合にも Seed Fu を実行させる。

db/seeds.rb に Seed Fu を使うように書いておくと、 間違って rake db:seed された場合にも Seed Fu が実行されるため便利だと思います。
その場合、以下の2点に気をつける必要があります。

1. fixture_path を設定

README には Fixtureファイルを探すパスのデフォルトは db/fixturesdb/fixtures/#{Rails.env} と記載されていますが、
これはrakeタスクを実行した場合のデフォルトです。
SeedFu.seed APIを使用する場合のデフォルトは db/fixtures です。
そのため、Rails.envに応じたFixtureファイルを使い分けたい場合には fixture_path の設定が必要です。

2. FILTER を変換

環境変数を用いて FILTER=users,articles のように適用するファイルを指定できますが、この環境変数の値をそのままAPIに渡しても期待通りに動きません。
正規表現に変換する必要があります。


以上の2点を踏まえた具体的な記述例は以下の通りです。

db/seeds.rb
paths = [Rails.root.join("db/fixtures"), Rails.root.join("db/fixtures/#{Rails.env}")]

filters = ENV["FILTER"].presence && /#{ENV["FILTER"].gsub(/,/, "|")}/

SeedFu.seed(paths, filters)

参考: https://github.com/mbleigh/seed-fu/blob/v2.3.9/lib/tasks/seed_fu.rake#L27

Tip2: FILTER の指定はファイル名の一部でOK

環境変数 FILTER で指定した文字列は正規表現に変換されて、ファイル名とマッチするか判定されます。
そのため、ファイル名の一部だけを指定しても部分一致するファイルが実行されます。
ファイル名の順番で実行されるため、ファイル名の先頭に連番をつけているケースが少なくないと思いますが、そのようなケースでは例えば FILTER=01,02 のような指定ができます。

前述の通り、正規表現として使用されるので、頑張れば除外するファイル名を指定することもできます。FILTER='^(?!users)' で「 users で始まるファイル以外」ということになります。

Tip3: Fixture ファイルの中で FactoryBot を使用する。

Seed Fu でも FactoryBot を使用できます。
しかし require や include が必要な場合には少し気をつける必要があります。
Fixtureファイルは API を呼び出した場所と同じコンテキストで実行されるため、require や include もそこで行う必要があります。

db/seeds.rb
require "factory_bot_rails"

include FactoryBot::Syntax::Methods

SeedFu.seed

これで Fixtureファイル内でもFactoryBotのメソッドを使用できます。(include しなくても FactoryBot.attributes_for のような形式であれば使用できます)

db/fixtures/users.rb
User.seed(
  :id,
  attributes_for(:user, id: 1, name: "Alice"),
  attributes_for(:user, id: 2, name: "Bob")
)

Tip4: 共通で使用するメソッドを作る

前述の FactoryBot と同様ですが、API を呼び出した場所にメソッドを定義したり、別ファイルに書いてそれを require すると、各Fixtureファイルで使用することができます。

db/utils.rb
def triple(num)
  num * 3
end
db/seeds.rb
require_relative "./utils"

def double(num)
  num * 2
end

SeedFu.seed
db/fixtures/users.rb
User.seed(
  :id,
  { :user, id: 1, num1: double(2), num2: triple(3) }
)

Tip5: シードデータのプリントを抑制する。

rake db:seed_fu を実行すると、標準では以下のような内容が出力されます。

== Seed from /path/to/app/db/fixtures/users.rb
 - User {:id=>1, :name=>"Alice"}
 - User {:id=>2, :name=>"Bob"}

データのプリントを抑制したい場合、 SeedFu.quiet = true をセットするとファイル名まで出力されなくなります。
そこで各Fixtureファイルでファイル名を出力するようにします。
ちなみに、Fixtureファイルは文字列として読み込まれ、evalされます。そのため puts "== #{__FILE__}" のように __FILE__ を使用できません。
代わりに filename を使用することができ、 puts "== Seed from #{filename}" と書けば各ファイルの正しいファイル名が出力できます。
ただし filename は公式のものではなく、evalされた場所でたまたま見えているローカル変数(メソッド引数)です。そのため将来のアップデート等で参照できなくなる可能性があります。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?