Open jasonkarns opened 3 years ago
@jasonkarns I took an initial swing at this and I'm not sure how feasible this is from the feature request side. You might be better off using explicit class definition on all Factories and conditionally defining the class by the Feature Flag.
class Test; end
class TestNew; end
FactoryBot.define do
factory :test, class: (feature_flag == 'legacy') ? "Test" : "TestNew" ; end
end
Description
FactoryBot.modify
doesn't allow changing a factory's class. It's not explicitly mentioned in the docs, so this could reasonably be classified as a feature request. Though I rather expected it to be possible.Reproduction Steps
Given:
Expected behavior
I expected
FactoryBot.build :test
to return an instance ofTestNew
.Actual behavior
System configuration
factory_bot version: 5.1.1 rails version: 6.0 ruby version: 2.6.5
Rationale
I'm sure this probably seems like an odd thing to do. Here's the scenario: We are migrating models from a legacy database, so we have the legacy db models defined is
Legacy::MyRecord
where each (or most) of the legacy models has a correspondingMyRecord
(no-namespace) which lives in the new database. The application code (including the existing factories) all referenceLegacy::*
.We are using a feature flag to allow the code to run where each
Legacy::*
constant is instead redefined to be the new class. (We're usingclass Legacy::Foo < Foo
to keep AR happy.) However, factory bot (and active record's) introspection doesn't allow the constant redefinition to "just work". For the AR associations to work, the factory bot factory needs to be of the right class.There are dozens of legacy models to be migrated, which means dozens of factories that we'd prefer not to duplicate. The hope was that we could use
.modify
to change each factory'sclass
when the feature flag is enabled. But this appears to have no effect.