FactoryGirl create_list pass in multiple values
Asked Answered
S

3

13

If I have this factory:

factory :product, class: Product do
  name        { Faker::Commerce.product_name }
  description { Faker::Lorem.paragraph }
  price       { Faker::Number.number(3) }
end

I can use create_list to create 2 products like this:

FactoryGirl.create_list(:product, 2)

but I want to pass in defaults to both my products, I would suppose something theoretically like this?:

prods = [{:name => "Product 1"},{:name => "Product 2"}]
FactoryGirl.create_list(:product, prods.count, prods)

I have searched for a while and cannot find the answer to this, is it possible using an elegant solution like create_list?

The reason I would like this solution is because :product is one of many child associations to a parent model. I would like a configurable way that I could generate the parent model factory through a single FactoryGirl.create command and pass in all the values I would like for child associations (through the use of FactoryGirl's traits and ignore blocks). I hope that makes sense. I could show a bunch of code here but I believe this provides enough context?

Synchroscope answered 14/7, 2015 at 7:24 Comment(0)
D
13

You can generate the list yourself:

data = [{:name => "Product 1"},{:name => "Product 2"}]
products = data.map { |p| FactoryGirl.create(:product, p) }

Which should leave you with an array of products.

Demetra answered 14/7, 2015 at 8:9 Comment(0)
P
8

Since v5.2.0 you can do this:

twenty_somethings = create_list(:user, 10) do |user, i|
  user.date_of_birth = (20 + i).years.ago
end
Phonemics answered 27/4, 2020 at 8:19 Comment(0)
H
1

I found this thread looking for a similar solution. If you are actually just wanting to sequence the name like your example, you can use sequence in the factory and then create_list -- which I found could be used as a trait as well. My need was to increment a timestamp when creating a list of records:

trait :sequentially_longer_ago do
  sequence(:created_at) { |n| n.days.ago }
end

and then:

create_list(:my_record, 123, :sequentially_longer_ago, foo: 'bar')

So in your case, it might be:

trait :sequence_product_name do
  sequence(:name) { |n| "Product #{n + 1}" }
end

and then:

create_list(:product, 123, :sequence_product_name, foo: 'bar')
Hereld answered 22/12, 2021 at 17:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.