以下の記事を追記するときにFactoryBotでfactory跨いで使いたいtraitを定義する方法調べていて見つけたのでMEMOしておきます📝
検証したバージョンはfactory_bot 6.1.0
です。
やりたいこと
以下のようなstrict loadingを使用したN+1を検知する設定 + strict laodingを無効化するためのメソッドを用意した実装を行っているとします。
class ApplicationRecord < ActiveRecord::Base self.strict_loading_by_default = true def strict_loading!(value = true) @strict_loading = value end end
上記を行ったけどテストコードではstrict loadingを一時的に無効化したい場合にtraitを使ってシンプルにかけるようにしたいというのがやりたいことになります。
describe '#foo' do let(:foo) { create(:foo, :strict_loaded) } before do create(:bar, foo: foo) end it { expect(foo.bars.length).to eq 1 } end
各factoryで個別にtraitを書くのは手間なのでglobalに以下のようなtraitを定義したいものです。
trait :strict_loaded do after(:build) { |record| record.strict_loading!(false) } end
globalに使えるtraitを定義する
globalに使えるtraitを定義する方法は簡単で以下のようにfactoryに紐付けずFactoryBot.define
直下にtraitを置くことで定義できます。
FactoryBot.define do trait :strict_loaded do after(:build) { |record| record.strict_loading!(false) } end end
全然知らなかったのですが、以下の通りテストコードでも検証されているので公式でサポートされている利用方法のようです👀✨
おわりに
FactoryBot便利ですね🤖✨