web-dev-qa-db-fra.com

Faker produit des données en double lorsqu'il est utilisé dans factory_girl

J'essaie de remplir de fausses données dans une usine à l'aide de la gemme Faker:

Factory.define :user do |user|
  user.first_name Faker::Name::first_name
  user.last_name Faker::Name::last_name
  user.sequence(:email) {|n| "user#{n}@blow.com" }
end

Cependant, même si je m'attends à ce que cela produise des utilisateurs qui ont des prénoms et des noms de famille différents, chacun est le même:

>> Factory(:user)
=> #<User id: 16, email: "[email protected]", created_at: "2011-03-18 18:29:33",     
updated_at: "2011-03-18 18:29:33", first_name: "Bailey", last_name: "Durgan">
>> Factory(:user)
=> #<User id: 17, email: "[email protected]", created_at: "2011-03-18 18:29:39", 
updated_at: "2011-03-18 18:29:39", first_name: "Bailey", last_name: "Durgan">

Comment puis-je obtenir la gemme Faker pour générer de nouveaux noms pour chaque utilisateur et pas seulement réutiliser les noms originaux?

85
Peter Nixey
Factory.define :user do |user|
  user.first_name { Faker::Name::first_name }
  user.last_name { Faker::Name::last_name }
  user.sequence(:email) {|n| "user#{n}@blow.com" }
end

Essayez de mettre des crochets autour des faussaires. voir ce lien

154
Will Ayd

Notez que Faker peut toujours fournir des données en double en raison de la quantité limitée de fausses données disponibles.

À des fins de test simples et pour obtenir des validations d'unicité, j'ai utilisé ce qui suit:

sequence(:first_name) {|n| Faker::Name::first_name + " (#{n})"}
sequence(:last_name) {|n| Faker::Name::last_name + " (#{n})"}
44
TwiceB

Par souci de préserver la bonne réponse, ici elle est transloquée du blog, je ne mets aucun crédit pour la réponse.

Si vous utilisez le code ci-dessous, Faker ne produira pas de noms uniques

Factory.define :user do |u|
  u.first_name Faker::Name.first_name
  u.last_name Faker::Name.last_name
end

Cependant, mettre des accolades bouclées autour de Faker le fait fonctionner!

Factory.define :user do |u|
  u.first_name { Faker::Name.first_name }
  u.last_name { Faker::Name.last_name }
end

Pour expliquer pourquoi, le premier exemple produit les mêmes noms. Il n'évalue qu'une seule fois. Le deuxième exemple évalue chaque fois que l'usine est utilisée.

Cela est dû au {} fournissant une évaluation paresseuse. Essentiellement, ils fournissent un proc/lambda avec l'appel Faker comme valeur de retour.

18
ocodo

Une alternative (moins efficace) à l'utilisation de séquences lorsque vous avez une validation d'unicité sur un attribut consiste à vérifier si une valeur proposée existe déjà et à en essayer de nouvelles jusqu'à ce qu'elle soit unique:

FactoryGirl.define do
  factory :company do
    name do
      loop do
        possible_name = Faker::Company.name
        break possible_name unless Company.exists?(name: possible_name)
      end
    end
  end
end
5
Dan Kohn