Reputation: 7855
I have an Item and Category. I want to have multiple Items, each with multiple Categories. I don't want each Item to have different Categories, but rather associate with a common set of Categories.
Is there a way to achieve this using the FactoryGirl dsl?
Here is how I did it using a helper module:
module Features
module ItemsHelpers
def create_items_with_categories
parents = create_list :category, 2
children = []
5.times do
children << (create :category, parent: parents.sample)
end
10.times do
item = build :item
item.categories << children.sample(3)
item.save
end
end
end
end
Upvotes: 0
Views: 1499
Reputation: 16012
By looking at the code, I assume, item has many categories:
sequence :name do |n|
"Item - #{n}"
end
factory :item do
name { generate(:name) }
# other fields here..
ignore do # in the latest version, it is: "transient do.."
categories_count 5
end
after(:create) do |item, evaluator|
categories { FactoryGirl.create_list(:category, evaluator.categories_count) }
end
end
You can use this as:
let(:categories) { create_list(:category, 10) }
let(:items) { create_list(:item, 5, categories: categories) }
UPDATE: In many cases, when your specs grow, you won't have to be bothered about adding extra: categories
while creating items
as it'll be created by the default values, unless specified. Hence, ignore/ transient for keeping it classy.
So you can do:
let(:items) { create_list(:items, 10, categories_count: 3) } # when you need just 3 categories per item!!
At the end, it comes down to the preference and the coding structure you follow. I prefer to have both so that I don't have to bother adding categories
list when cretaing item
or items
factory.
Upvotes: 1