FactoryBotのsequenceをスコープごとに生成するgemの紹介

※この記事は 2024年06月26日に Medium で公開されたものを、ブログ移行に伴い再掲載したものです。内容は当時のままですので、一部情報が古くなっている可能性があります。

Tebiki株式会社で「tebiki」のプロダクトエンジニアをしている日笠です。今回はtebikiで利用しているgemのニッチな使いづらさを解消したことについてお話しします。

tebikiは、製造業/物流業/食品業/小売業/飲食業などの現場でノウハウを可視化し効率的な教育を可能にするプロダクトです。tebikiはRuby on Railsで開発されており自動テストのデータ生成にFactoryBotを利用しています。

FactoryBotの機能の一つに、生成するデータそれぞれに連番を振ってくれる sequence というものがあります。sequence はデータを作る度に内部で持っているポインタをインクリメントすることで連番を生成します。

以下は toBサービスによくある会社に所属する従業員を扱うドメインのコードで、ここでは従業員番号を生成しています。

FactoryBot.define do
  factory :employee do
    sequence(:employee_number)
  end
end

FactoryBot.create(:employee).employee_number # => 1
FactoryBot.create(:employee).employee_number # => 2

このように sequence を設定することで勝手に連番を生成してくれます。

ところで、従業員は会社に所属し、会社ごとに従業員に対して従業員番号を発行するので会社が違えば同じ従業員番号が存在して問題ないはずです。しかし、 sequence はスコープを持たないため、このサンプルコードでは別の会社のデータを生成しても従業員番号はそれを引き継いだ連番になってしまいます。

FactoryBot.define do
  factory :employee do
    association :company
    sequence(:employee_number)
  end
end

company_1 = FactoryBot.create(:company)
company_2 = FactoryBot.create(:company)
FactoryBot.create(:employee, company: company_1).employee_number # => 1
FactoryBot.create(:employee, company: company_2).employee_number # => 2 // company_2のemployeeはまだ生成していないので1になって欲しい

このような実態に即していないテストデータでテストしたくないですし、このために連番を手書きで入力するのも手間です。ですが実際このようなケースは至る所で発生します。

スコープ付きのsequence

そこで factory_bot-scoped_sequence というgemを作りました。

このgemでは、先ほど紹介した sequence の定義を拡張して連番を適用するスコープを持たせられるようにしています。

先程の例では以下のように会社毎のスコープで連番が生成できるようになります。

FactoryBot.define do
  factory :employee do
    association :company
    sequence(:employee_number, scope: :company_id)
  end
end

company_1 = FactoryBot.create(:company)
company_2 = FactoryBot.create(:company)
FactoryBot.create(:employee, company: company_1).employee_number # => 1
FactoryBot.create(:employee, company: company_1).employee_number # => 2
FactoryBot.create(:employee, company: company_2).employee_number # => 1

scope を指定しなければ今まで通りの挙動になるので入れておいて損はないと思います。

というわけで、Tebikiでは開発の手間を削減するようなアイデアを実装しつつサービスを成長させるエンジニアを募集しています。よろしくお願いします。

▼採用HP

https://tebiki.co.jp/recruit.html

▼募集中のエンジニア求人一覧

https://herp.careers/v1/tebiki/requisition-groups/2514f131-4e3b-4f50-9539-27aa01a6639f