以下の内容はhttps://shinkufencer.hateblo.jp/entry/2023/12/23/000000より取得しました。


factory bot の trait内に引数のように値を渡したい場合はtransientを使う

N:Nの関連性のレコードをサッとつくるためのtraitを作りたい場合のtips

環境

Gemfile.lockは以下のような環境

factory_bot (6.4.4)
  activesupport (>= 5.0.0)
factory_bot_rails (6.4.2)
  factory_bot (~> 6.4)
  railties (>= 5.0.0)

使い方

factory_botでは一時的な属性情報として transient という機構を用意している。公式ドキュメントとしては以下のように紹介されている。

factory :user do
  transient do
    rockstar { true }
  end

  name { "John Doe#{" - Rockstar" if rockstar}" }
end

create(:user).name
#=> "John Doe - ROCKSTAR"

create(:user, rockstar: false).name
#=> "John Doe"

Transient Attributesより引用

これをtraitと組み合わせることにより、trait側に値を渡す事ができる。

利用例

たとえば以下のようなN:Nを表現するテーブルがあるとする。

booksテーブルとshopsテーブルをつなぐ「本屋さんがおすすめする本」という関連性

この場合にbooksのレコードを作るときにshopsのレコードを指定したい場合、以下のようなtraitを作成する。

# 前提としてshopとbook_recommend_shopのFactoryBotのファイルはあること
FactoryBot.define do
  factory :book do
    title { "BookTitle#{rand(100)}" }
    author
  end
  trait :recommend_shop do
    # 意図したものをセットできるようにする
    transient do
      related_recommend_shop_record { nil }
    end
    after(:create) do |self_object, evaluator|
      shop = evaluator.related_recommend_shop_record.nil? ? create(:shop) : evaluator.related_recommend_shop_record
      create(:book_recommend_shop, book: self_object, shop: shop)
    end
  end
end

このように作成すれば、以下のようにshopを簡潔にしていしてつくることができる。

choice_shop = create(:shop)
create(:book,:recommend_shop,related_recommend_shop_record: choice_shop)

こうすることで間の交差テーブルを意識することなくレコードをつくる仕組みを用意することができる。

参考サイト




以上の内容はhttps://shinkufencer.hateblo.jp/entry/2023/12/23/000000より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14