FactoryGirl + Faker - même les données générées pour chaque objet de db graines de données
-
26-12-2019 - |
Question
Je suis à l'aide de FactoryGirl et Faker pour générer des objets utilisateur dans mon seeds.rb
fichier mais pour une raison quelconque exactement le même utilisateur est créé et rake db:seed
qui est défectueux en raison d'un e-mail de l'unicité de validation.
Usine pour les utilisateurs:
#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
Et le code de la seeds.rb
fichier:
#seeds.rb
rand(5..11).times { FactoryGirl.create(:user) }
Erreur:
ActiveRecord::RecordInvalid: Validation failed: Email has already been taken
Si j'ouvre la console et l'utilisation FactoryGirl.create(:user)
J'obtiens les mêmes résultats...même objet est créé plus et plus de même si, si je lance juste Faker::Internet.email
plusieurs fois, je vais obtenir plusieurs e-mails.
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 par lui-même:
[3] pry(main)> Faker::Internet.email
=> "hobart_purdy@goodwinmills.org"
[4] pry(main)> Faker::Internet.email
=> "pierce_brekke@gislasonrolfson.net"
Ce qui me manque ici?Pourquoi est-Faker produisant les mêmes données à chaque fois lorsqu'ils sont utilisés par FactoryGirl?
La solution
Vous avez besoin pour passer un bloc si vous voulez que les valeurs de la ré-évaluée pour chaque instance créée.
Au lieu de
email Faker::Internet.email
essayez...
email { Faker::Internet.email }
Autres conseils
À l'aide de Faussaire pour obtenir l'unicité de passage d'attributs peut être un anti-modèle.Il peut aussi être une mauvaise idée d'avoir Faker est semi-aléatoire de sortie dans les tests - ce que si parfois les tests d'échouer et vous partez pour un wild goose chase juste parce que Faker toussa jusqu'à une valeur que vous n'attendiez pas?
Dernièrement, j'ai été en utilisant FactoryGirl de séquences pour obtenir prévisible, mais l'unicité de transmission de valeurs.
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"
Prises de Factory Girl conseils @ http://arjanvandergaag.nl/blog/factory_girl_tips.html