mrateb
mrateb

Reputation: 2499

Ruby Faker::Name.unique validation failed

I have a simple factory where I create categories with unique names

FactoryBot.define do
  factory :category do
    name_en Faker::Name.unique.first_name
  end
end

And in my spec files, I use this to create categories as such:

create_list(:category,2)

Now my problem is, I keep getting:

ActiveRecord::RecordInvalid Exception: Validation failed: Name en has already been taken

If I debug and try to call Faker::Name.unique.first_name myself, it shows a unique name for each call. Using create(:category) however shows the error seen above. What am I doing wrong?

Upvotes: 1

Views: 400

Answers (2)

Geovany Gameros
Geovany Gameros

Reputation: 48

Faker has a .unique method that is supposed to do what you're looking for. This is the one you're using in your example.

FactoryBot.define do
  factory :category do
    name_en Faker::Name.unique.first_name
  end
end

However, I've found it problematic when creating many records. It could raise a Faker::UniqueGenerator::RetryLimitExceeded: Retry limit exceeded for name error.

You could use the sequence approach:

FactoryBot.define do
  factory :category do
    sequence(:name_en) { |n| "#{Faker::Name.unique.first_name} #{n}" }
  end
end

But first, be sure that you want to set a unique name to all new records instead of explicitly assigning a meaningful name every time you create them. Thoughtbot considers this practice an antipattern as they say in this blog post

Upvotes: 1

Ritesh Choudhary
Ritesh Choudhary

Reputation: 782

Use sequence for name_en field for uniq names

FactoryGirl.define do
  factory :category do
    sequence :name_en, 'AAA0' do |sr|
      "#{Faker::Name.first_name}#{sr}"
    end
  end
end

Upvotes: 2

Related Questions