I made a many-to-many relationship with Rspec and tested it with SystemSpec. Due to the complexity of the original table structure, I had a lot of trouble, so I will summarize the notes below.
The execution completion is as follows.
The table structure looks like this. The main tables are ʻoffices (branch office of a company) and
shops (stores that are business destinations), and ʻoffice
(branch office) opens ʻevebt, and the stores
shopsthat are business destinations there.
Join. shops
always has some category
.
Due to the model method, when I made factory
of ʻevents, I needed
shops` associated with it. However, due to the structure, if I wrote it like this, an error occurred.
let!(:shop){FactoryBot.create(:shop)}
let!(:event){FactoryBot.create(:event)}
#=>Here, the structure was such that an error would occur if there was no shop associated with the event.
let!(:event_shops){FactoryBot.create(:event_shop, event: event, shop: shop)}
Therefore, I decided to create a factory that can define the related shop
at the same time when the factory
of ʻevent` is created.
The created Factory is as follows.
spec/factories/events.rb
FactoryBot.define do
factory :event do
office_id { nil }
name { "Test event" }
trait :with_shops do
after(:create) do |event|
category = FactoryBot.create(:category, :sequence)
create_list(:shop, 1, events: [event], category: category)
end
end
end
end
First, create a trait called with_shops
in the factory of ʻevent so that you can also create the associated
shop when you create ʻevent
. Make it possible to create multiple shop
factories with create_list
(only one because only one is needed here), and [event] so that multiple instances of ʻevent
can be entered from ʻevents. It is expressed as
and an array.
In addition, I will explain later that category
is purposely called using trait
.
spec/factories/categories.rb
FactoryBot.define do
factory :category do
name { "Medical system" }
trait :sequence do
sequence(:id, 100)
name { "Clothing system" }
end
end
end
spec/system/events_spec.rb
let!(:event) { FactoryBot.create(:event, :with_shops, office: office, shops: [shop]) }
#You can't apply category to shop from here
Next, in the factory of category
, ʻeventis generated multiple times in the view. Therefore, the
cateogory of the
shop generated at the same time must be set to a different ʻid
(FK) each time, or an FK duplicate error will occur.
Also, when trying to apply category
from system spec
to shops
of ʻevent, when trying to create a factory for
shopin
spec / factories / events.rb`," The foreign key does not exist "and I got an error.
Therefore, using sequence
, I tried to create different categories of ʻid` (FK) one by one.
It took a long time to resolve, but I'm glad I managed to resolve it! This time, the structure of the DB was complicated, so I had to write such a complicated Spec, but In the future, I would like to solidify the DB design so that simpler tests can be done. .. .. ..
▼ Articles that I especially referred to -Set up "many-to-many" and "multiple one-to-many" associations in Factory Girl -Use Factorybot traits to prepare data with complex associations with double has_many -FactoryBot (formerly FactoryGirl) sequence and .next
Recommended Posts