n350071のブログ

主にRubyなフリーランスエンジニア

Factorybotのtraitを使って、has_manyが2重にある複雑なassociation付きのデータを用意する

2019-08-24 n350071RSpec

🤔 状況

たとえば、「著者が本を持ち、本は表紙を持つ」という親子孫のリレーションがあるとします。

テストデータとして「本を一冊出版し、その本には表紙が2つある著者を用意したい」とき、Factorybotでは、以下に書くようにtraitを使うと都合がよいです。

class Author
  has_many :books
  has_many :title_covers, through: :book
end

class Book
  belongs_to :author
  has_many :title_covers
end

class TitleCover
  belongs_to :author
  belongs_to :book
end

🤩 Factorybotのtraitを用意する

buildのときは<<
build_listのときは=
でリレーションを作っています。

FactoryBot.define do
  factory :author, class: Author do

    trait :with_a_book_and_title_covers do
      after(:build) do |author|
        author.books << FactoryBot.build(:book, :with_title_covers)
      end
    end

  end
end

FactoryBot.define do
  factory :book, class: Book do

    trait :with_title_covers do
      after(:build) do |book|
        book.title_covers = FactoryBot.build_list(:title_cover, 2)
      end
    end

  end
end

🎉 traitを使ってデータを用意する

このtraitを使うと「本を一冊出版し、その本には表紙が2つある著者」を簡単に用意できます。
なお、authorの名前を引数で与えてみました。

let(:author){ create(:author, :with_a_book_and_title_covers, name: 'n350071') }

📚 参考になったリンク