FactoryGirl + Faker – für jedes Objekt in den Datenbank-Seed-Daten werden dieselben Daten generiert
-
26-12-2019 - |
Frage
Ich verwende FactoryGirl und Faker, um Benutzerobjekte in meinem zu generieren seeds.rb
Datei, aber aus irgendeinem Grund wird genau derselbe Benutzer erstellt und rake db:seed
schlägt aufgrund einer E-Mail-Eindeutigkeitsüberprüfung fehl.
Fabrik für Benutzer:
#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
Und der Code drin seeds.rb
Datei:
#seeds.rb
rand(5..11).times { FactoryGirl.create(:user) }
Fehler:
ActiveRecord::RecordInvalid: Validation failed: Email has already been taken
Wenn ich die Konsole öffne und verwende FactoryGirl.create(:user)
Ich erhalte die gleichen Ergebnisse ... das gleiche Objekt wird immer wieder erstellt, auch wenn ich es nur ausführe Faker::Internet.email
mehrmals bekomme ich mehrere 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 für sich:
[3] pry(main)> Faker::Internet.email
=> "hobart_purdy@goodwinmills.org"
[4] pry(main)> Faker::Internet.email
=> "pierce_brekke@gislasonrolfson.net"
Was fehlt mir hier?Warum erzeugt Faker jedes Mal dieselben Daten, wenn es über FactoryGirl verwendet wird?
Lösung
Sie müssen einen Block übergeben, wenn Sie möchten, dass die Werte für jede erstellte Instanz neu ausgewertet werden.
Anstatt
email Faker::Internet.email
versuchen...
email { Faker::Internet.email }
Andere Tipps
Die Verwendung von Faker zum Erhalten von Eindeutigkeitsübergabeattributen kann ein Anti-Muster sein.Es kann auch eine schlechte Idee sein, die halbzufällige Ausgabe von Faker in Tests zu verwenden – was ist, wenn Tests manchmal einfach fehlschlagen und Sie sich auf eine wilde Gänsejagd begeben, nur weil Faker einen Wert ausgegeben hat, mit dem Sie nicht gerechnet haben?
In letzter Zeit verwende ich die Sequenzen von FactoryGirl, um vorhersehbare, aber dennoch eindeutige Werte zu erhalten.
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"
Entnommen aus Factory Girl-Tipps @ http://arjanvandergaag.nl/blog/factory_girl_tips.html