Techioz Blog

FactoryBot にグローバルに機能を追加するにはどうすればよいですか?

概要

FactoryBot を拡張して Rails の .first_or_create をコピーする機能を組み込んだクラスがあります。

module FactoryBotFirstOrCreate
  def first(type, args)
    klass = type.to_s.camelize.constantize

    conditions = args.first.is_a?(Symbol) ? args[1] : args[0]

    if !conditions.empty? && conditions.is_a?(Hash)
      klass.where(conditions).first
    end
  end

  def first_or_create(type, *args)
    first(type, args) || create(type, *args)
  end

  def first_or_build(type, *args)
    first(type, args) || build(type, *args)
  end
end

それを SyntaxRunner クラスに追加できます

module FactoryBot
  class SyntaxRunner
    include FactoryBotFirstOrCreate
  end
end

工場内でアクセスするには

# ...
after(:create) do |thing, evaluator|
  first_or_create(:other_thing, thing: thing)
end

しかし、これを工場外で使おうとするとアクセスできません…。

これらの手順をすべて実行しても、依然として NoMethodError: unknown method first_or_create が発生します。

FactoryGirl の作成と同じようにこのメソッドにアクセスできるようにするには、何を含めるか、その他の方法で構成できますか?

解決策

@engineersmnky によると、FactoryBot の拡張機能

module FactoryBot
  extend FactoryBotFirstOrCreate
end

それならこれはうまくいきます

my_foo = first_or_create(:everything, is: :awesome, if_we: :work_together)