Avoiding Duplicates in a Ruby on Rails Factory Girl Factory with Fake I have a Factory Girl factory that needs to generate a unique name using Faker. Unfortunately, Factory Girl generates duplicates relatively frequently, which causes intermittent test errors. I previously added a random integer after the Faker name, but I am now checking the database to make sure that a potential name from Faker doesn't already exist.

FactoryGirl.define do
  factory :company do
    name do
      name = Faker::Company.name
      name = Faker::Company.name while Company.exists?(name: name)
      name
    end
  end
end


The above code works but seems inelegant. I'm assigning name in the first row of the block so that only one DB lookup (instead of two) will be necessary in the most common case where a Fake name is unique.

I end the block with name as otherwise the while statement returns nil when the loop ends.
The simplest thing to do is probably to use FactoryGirl's sequence:

FactoryGirl.define do
  factory :company do
    sequence(:name) { |n| "#{Faker::Company.name} #{n}" }
  end
end


sequence basically gives you an auto-incrementing integer, so you can avoid uniqueness issues. Sure, it'll generate some slightly odd company names, but for testing that shouldn't matter much.

In general though, I don't feel too great a need for something like Faker. Something like this should work just as well:

FactoryGirl.define do
  factory :company do
    sequence(:name) { |n| "Acme Inc. #{n}" }
  end
end


If it's only your specs looking at the data, it doesn't really matter if the company name's "Acme", "foobar 42", or "ACC8B1B7-7EC0-4F05-AB2A-B487C134F6BF".

Besides, your current solution is:


non-deterministic, so it may never exit the while loop if it just happens to keep picking the same couple names again and again,
but even if we ignore that, the act of adding more tests that use company records, will mean more name collisions and longer time spent in the loop. I don't know how Faker works, but (unlikely but technically possible) you might even end up exhausting every name Faker can come up with, and end up looping forever.