Upgrade to Pro — share decks privately, control downloads, hide ads and more …

FactoryBotアンチパターン / factory_bot anti-patterns

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers. →
Avatar for toshimaru toshimaru
October 05, 2026

FactoryBotアンチパターン / factory_bot anti-patterns

[Kaigi on Rails 2026 過去登壇勉強会 - connpass](https://connpass.com/event/406332/) での発表資料です。

Avatar for toshimaru

toshimaru

October 05, 2026

More Decks by toshimaru

Other Decks in Technology

Transcript

  1. 自己紹介 toshimaru 2025年6月〜 SmartBank Inc. 推しモデル: GPT-6 Astra Opus5.5 FactoryBot

    アンチパターン 2 Kaigi on Rails 2026 過去登壇勉強会
  2. 発表当時の状況 • コロナ禍のため、ビデオ登壇 • 「rspec の正しい書き方」 みたいな話は巷にあった • FactoryBot に特化した話は巷に見かけなかった

    • rubocop-factory_bot 未リリース • 2023年5月: rubocop-factory_bot リリース • 正確に言うと、rubocop-rspec に RSpec/FactoryBot/* が内包されていたが、そ こまでルールが多くなく、あまり活用されていなかった FactoryBot アンチパターン 9 Kaigi on Rails 2026 過去登壇勉強会
  3. 紹介するアンチパターン 01 巨大デフォルトデータ 05 独自 sequence id 02 無駄 create

    06 同じ値のテスト 03 Too Many Traits 07 無駄 list 生成 04 DRY じゃない Traits 08 Always Create Association ※ それぞれのアンチパターンの詳細については、オリジナル資料を参照 FactoryBot アンチパターン 15 Kaigi on Rails 2026 過去登壇勉強会
  4. 前提 class User < ApplicationRecord has_many :posts end class Post

    < ApplicationRecord belongs_to :user end FactoryBot アンチパターン 17 Kaigi on Rails 2026 過去登壇勉強会
  5. Bad FactoryBot.define do factory :user do sequence(:id) name { "User

    Name" } after(:create) do |user| create_list(:post, 10, user: user) end end end FactoryBot アンチパターン 18 Kaigi on Rails 2026 過去登壇勉強会
  6. Bad FactoryBot.define do factory :user do sequence(:id) name { "User

    Name" } after(:create) do |user| create_list(:post, 10, user: user) end end end FactoryBot アンチパターン 19 独自 sequence id 同じ値のテスト 巨大デフォルトデータ 無駄 list 生成 Kaigi on Rails 2026 過去登壇勉強会
  7. Good FactoryBot.define do factory :user do sequence(:name) { |n| "User

    Name#{n}" } # Faker::Name.name でも OK trait :with_posts do transient do posts_count { 3 } end after(:create) do |user, evaluator| create_list(:post, evaluator.posts_count, user: user) end end end end FactoryBot アンチパターン 20 Kaigi on Rails 2026 過去登壇勉強会
  8. Bad FactoryBot.define do factory :user do role { :general }

    trait :admin do role { :admin } end trait :deleted do deleted_at { Time.current } end trait :deleted_admin do role { :admin } deleted_at { Time.current } end end end # 呼び出し側 FactoryBot.create(:user, :deleted_admin) FactoryBot アンチパターン 22 Kaigi on Rails 2026 過去登壇勉強会
  9. Bad FactoryBot.define do factory :user do role { :general }

    trait :admin do role { :admin } end trait :deleted do deleted_at { Time.current } end trait :deleted_admin do role { :admin } deleted_at { Time.current } end end end DRY でない traits • • :admin と重複 :deleted と重複 # 呼び出し側 FactoryBot.create(:user, :deleted_admin) FactoryBot アンチパターン 23 Kaigi on Rails 2026 過去登壇勉強会
  10. Good FactoryBot.define do factory :user do role { :general }

    trait :admin do role { :admin } end trait :deleted do deleted_at { Time.current } end end end # 呼び出し側 FactoryBot.create(:user, :admin, :deleted) FactoryBot アンチパターン 24 Kaigi on Rails 2026 過去登壇勉強会
  11. Bad FactoryBot.define do factory :post do sequence(:title) { |n| "Post

    Title #{n}" } user { create(:user) } trait :title_blank do title { '' } end trait :title_too_long do title { 'a' * 1000 } end end end FactoryBot アンチパターン 26 Kaigi on Rails 2026 過去登壇勉強会
  12. Bad FactoryBot.define do factory :post do sequence(:title) { |n| "Post

    Title #{n}" } user { create(:user) } trait :title_blank do title { '' } end Too Many Traits 例外値 trait trait :title_too_long do title { 'a' * 1000 } end end end FactoryBot アンチパターン Always Create Association Too Many Traits 例外値 trait 27 Kaigi on Rails 2026 過去登壇勉強会
  13. Good FactoryBot.define do factory :post do sequence(:title) { |n| "Post

    Title #{n}" } user { association :user } # 単に user だけも可 end end FactoryBot アンチパターン 28 Kaigi on Rails 2026 過去登壇勉強会
  14. Bad RSpec.describe Post do describe "validations" do it "title が空なら

    invalid" do post = create(:post) post.title = "" expect(post).to be_invalid end end end FactoryBot アンチパターン 30 Kaigi on Rails 2026 過去登壇勉強会
  15. Bad RSpec.describe Post do describe "validations" do it "title が空なら

    invalid" do post = create(:post) post.title = "" expect(post).to be_invalid end end end FactoryBot アンチパターン 31 無駄 create Kaigi on Rails 2026 過去登壇勉強会
  16. Good RSpec.describe Post do describe "validations" do it "title が空なら

    invalid" do post = build(:post, title: '') expect(post).to be_invalid end end end FactoryBot アンチパターン 32 Kaigi on Rails 2026 過去登壇勉強会
  17. Other Tips FactoryBot.lint Rails Enum Traits 登録されている Factory を実際に一 Active

    Record モデルで定義された 通り生成してみて、バリデーション エラーや例外が発生しないかを チェック enum の各値に対応する trait を自動 FactoryBot アンチパターン 的に定義してくれる 34 Kaigi on Rails 2026 過去登壇勉強会