factory_bot icon indicating copy to clipboard operation
factory_bot copied to clipboard

Configurable ID factory for build_stubbed

Open olivier-thatch opened this issue 1 year ago • 0 comments

Problem this feature will solve

We use a slightly unconventional ID scheme in our DB. Rather than the usual auto-incrementing IDs or UUIDs, we use string IDs like those found in Stripe's API. (Basically our IDs look like <prefix>_<uuid> where prefix is unique to each model class, but that's not relevant to the request.)

Today, FactoryBot only supports auto-incrementing IDs or UUIDs when building stubbed models.

Desired solution

It would be great if there was a way to provide a callable to FactoryBot to be used to generate IDs for stubbed models. What I had in mind was something like this:

FactoryBot.build_stubbed_id_factory = lambda do |result_instance|
  if funky_model_has_custom_id_generator?(result_instance)
    generate_custom_id(result_instance)
  end

FactoryBot would use the ID factory if it's defined and returns a non-nil result, or fall back to the current behavior otherwise.

Alternatives considered

Right now we're directly patching FactoryBot, but that's obviously not great.

Here's our patch FWIW:

module FactoryBot
  module Strategy
    class Stub
      orig_next_id = instance_method(:next_id)
      define_method(:next_id) do |result_instance|
        if result_instance.class.respond_to?(:generate_id)
          result_instance.class.generate_id
        else
          orig_next_id.bind_call(self, result_instance)
        end
      end
      private :next_id
    end
  end
end

Additional context

I'm happy to submit a PR for this feature if you think it would be a nice addition to the gem.

olivier-thatch avatar Dec 08 '23 19:12 olivier-thatch