FactoryGirl + Faker - Stessi dati generati per ogni oggetto nei dati del seme DB
-
26-12-2019 - |
Domanda
Sto usando FactoryGirl e Faker per generare oggetti utente nel mio file seeds.rb
, ma per qualche motivo viene creato lo stesso identico utente e rake db:seed
è fallito a causa di una convalida di unicità e-mail.
Fabbrica per gli utenti:
#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
.
E il codice nel file seeds.rb
:
#seeds.rb
rand(5..11).times { FactoryGirl.create(:user) }
.
Errore:
ActiveRecord::RecordInvalid: Validation failed: Email has already been taken
Se apro la console e usi FactoryGirl.create(:user)
ottengo gli stessi risultati ... Lo stesso oggetto viene creato finito e ancora anche se eseguo solo Faker::Internet.email
diverse volte ottenere diverse e-mail.
Factorygirl:
[1] pry(main)> FactoryGirl.create(:user)
...
=> #<User id: 3, first_name: "Osvaldo", last_name: "Wunsch", email: "willy@damore.net", 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 da solo:
[3] pry(main)> Faker::Internet.email
=> "hobart_purdy@goodwinmills.org"
[4] pry(main)> Faker::Internet.email
=> "pierce_brekke@gislasonrolfson.net"
.
Cosa mi manca qui?Perché Faker produce gli stessi dati ogni volta quando viene utilizzato tramite FactoryGirl?
Soluzione
È necessario passare un blocco se si desidera rivalutare i valori per ogni istanza creata.
invece di
email Faker::Internet.email
.
prova ...
email { Faker::Internet.email }
. Altri suggerimenti
L'uso di Faker per ottenere attributi che passano unicità possono essere un anti-pattern.Potrebbe anche essere una cattiva idea avere l'output semi-casuale di Faker in test - cosa succede se a volte i test falliscono e tu sei fuori a una caccia all'oca selvaggia solo perché Faker ha tossito un valore che non ti aspettavi?
Ultimamente Ho usato le sequenze di FactoryGirl per ottenere valori prevedibili, ma unicizzanti.
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 #=> "email1@example.com"
FactoryGirl.create(:user).email #=> "email2@example.com"
.
Preso da Factory Girl Tips @ http://arjanvandergaag.nl/blog/factory_girl_tips.html