FactoryGirl + Faker - same data being generated for every object in db seed data
Solution 1
You need to pass a block if you want the values re-evaluated for each instance created.
Instead of
email Faker::Internet.email
try...
email { Faker::Internet.email }
Solution 2
Using Faker to get uniqueness-passing attributes may be an anti-pattern. It may also be a bad idea to have Faker's semi-random output in tests - what if sometimes tests just fail and you are off to a wild goose chase just because Faker coughed up a value you did not expect?
Lately I have been using FactoryGirl's sequences to get predictable, yet uniqueness-passing values.
FactoryGirl.define do
factory :user do
sequence(:first_name, 1) { |n| "John#{n}" }
sequence(:last_name, 1) { |n| "Doe#{n}" }
sequence(:phone, 1) { |n| (111111111+n).to_s }
sequence(:email, 1) { |n| "email#{n}@example.com" }
password "password"
password_confirmation "password"
end
end
FactoryGirl.create(:user).email #=> "[email protected]"
FactoryGirl.create(:user).email #=> "[email protected]"
Taken from Factory Girl tips @ http://arjanvandergaag.nl/blog/factory_girl_tips.html
sixty4bit
Updated on June 16, 2022Comments
-
sixty4bit almost 2 years
I am using FactoryGirl and Faker to generate user objects in my
seeds.rb
file but for some reason the exact same user is being created andrake db:seed
is failing because of an email uniqueness validation.Factory for users:
#users.rb require 'faker' FactoryGirl.define do factory :user do first_name Faker::Name.first_name last_name Faker::Name.last_name phone Faker::PhoneNumber.cell_phone email Faker::Internet.email password "password" password_confirmation "password" end end
And the code in
seeds.rb
file:#seeds.rb rand(5..11).times { FactoryGirl.create(:user) }
Error:
ActiveRecord::RecordInvalid: Validation failed: Email has already been taken
If I open the console and use
FactoryGirl.create(:user)
I get the same results...same object is being created over and over even though if I run justFaker::Internet.email
several times I'll get several e-mails.FactoryGirl:
[1] pry(main)> FactoryGirl.create(:user) ... => #<User id: 3, first_name: "Osvaldo", last_name: "Wunsch", email: "[email protected]", phone: "(912)530-4949 x64848", created_at: "2014-07-31 20:57:27", updated_at: "2014-07-31 20:57:27", encrypted_password: "$2a$10$mxWC7yLYR0m/Sw8MO6Lyru.xuTHCdCEuM9Orx3LXGApF...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil> [2] pry(main)> FactoryGirl.create(:user) ... ActiveRecord::RecordInvalid: Validation failed: Email has already been taken
Faker by itself:
[3] pry(main)> Faker::Internet.email => "[email protected]" [4] pry(main)> Faker::Internet.email => "[email protected]"
What am I missing here? Why is Faker producing the same data every time when used through FactoryGirl?