Simplified Example:
I recently setup Single Table Inheritance
on an Animal
model. Cat
and Dog
are subclasses of Animal
.
I have an Animal
factory :
factory :animal do
type { ["Dog","Cat"] }.sample
end
Almost everywhere in my test suite I call
let(:animal) { Factory.create(:animal) }
because the type of Animal
is irrelevant for the test. Since moving to STI I am getting errors where I perform equality checks on these animals because the superclass Animal
is returned by the factory but when associated objects instantiate Animal
they return the subclass.
Example:
expect(zoo.animal).to eq(animal)
fails with:
expected: #<Cat:0x007fa01a8cd360 same_other_attributes...>
actual: #<Animal:0x007fa01b8d33b8 same_other_attributes...>
Is there a way I can change the Animal
factory to return an instance of its subclass?
I did try calling .reload
on the Animal
after the factory creates it but it did not trigger reloading the new (sub)class. I know normally you can call superclass.becomes!(subclass)
to force the change but don't know how to put that in a FactoryGirl
callback in a way that will actually return the converted object.