I have an object, let's call it a TransitProvider.
It isn't an ActiveRecord object. It uses ActiveModel but it's designed to pull (or persist) it's data from two separate tables, a Provider table and a TransitService table. (reason being: the concept of "Transit Provider" is a concept that is made up of a Provider that offers a Transit Service).
So this is working well, except when I try to build a Factory (using FactoryBot) for the TransitProvider.
It doesn't have a table, so I can't "create" one. Instead, I'd need to actually create the underlying Provider and TransitService.
But I don't know how to do that in FactoryBot.
I want to be able to do stuff like:
let(:transit_provider) { create(:transit_provider, name: "Some Name") }
and have it "under the covers" actually create the Provider and the TransitService and then populate the ActiveModel TransitProvider with data from both.
Help?!
CodePudding user response:
Thoughtbot recently wrote a blog post on this subject, and FactoryBot's README has a section on creating factories for non-AR Ruby classes. Notably, the implementation relies on initialize_with
to instantiate the factory using a custom block, rather than the default behavior of calling new
without any arguments on what is assumed to be an AR model.
In your scenario, I would imagine a TransitProvider
factory that looks something like:
factory :transit_provider do
provider { create(:provider) }
transit_service { create(:transit_service) }
initialize_with { new(provider, transit_service) }
end
Also important to note that create
will never work for the above factory since that attempts to instantiate a model and persist a record in the DB. You'll want to build
this factory instead.