web-dev-qa-db-fra.com

FactoryGirl + Faker - mêmes données générées pour chaque objet dans les données de base de la base de données

J'utilise FactoryGirl et Faker pour générer des objets utilisateur dans mon fichier seeds.rb Mais pour une raison quelconque, le même utilisateur est en cours de création et rake db:seed Échoue en raison d'une validation de l'unicité de l'e-mail.

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 dans le fichier seeds.rb:

#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 utilise FactoryGirl.create(:user) j'obtiens les mêmes résultats ... le même objet est créé encore et encore même si je lance plusieurs fois Faker::Internet.email Plusieurs fois j'obtiendrai plusieurs e -mails.

Ouvrière:

[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 seul:

[3] pry(main)> Faker::Internet.email
=> "[email protected]"
[4] pry(main)> Faker::Internet.email
=> "[email protected]"

Qu'est-ce que j'oublie ici? Pourquoi Faker produit-il les mêmes données à chaque fois lorsqu'il est utilisé via FactoryGirl?

38
sixty4bit

Vous devez passer un bloc si vous souhaitez que les valeurs soient réévaluées pour chaque instance créée.

Au lieu de

email   Faker::Internet.email

essayer...

email   { Faker::Internet.email }
105
SteveTurczyn

L'utilisation de Faker pour obtenir des attributs de passage d'unicité peut être un anti-modèle. Il peut également être une mauvaise idée d'avoir la sortie semi-aléatoire de Faker dans les tests - que se passe-t-il si parfois les tests échouent et que vous partez pour une chasse aux oies sauvages juste parce que Faker a craché une valeur à laquelle vous ne vous attendiez pas?

Dernièrement, j'ai utilisé les séquences de FactoryGirl pour obtenir des valeurs prévisibles, mais uniques.

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]"

Tiré des conseils de Factory Girl @ http://arjanvandergaag.nl/blog/factory_girl_tips.html

11
Epigene