FactoryGirl + Faker: se generan los mismos datos para cada objeto en los datos semilla de la base de datos
-
26-12-2019 - |
Pregunta
Estoy usando FactoryGirl y Faker para generar objetos de usuario en mi seeds.rb
archivo pero por alguna razón se está creando exactamente el mismo usuario y rake db:seed
está fallando debido a una validación de unicidad del correo electrónico.
Fábrica para usuarios:
#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
Y el código en seeds.rb
archivo:
#seeds.rb
rand(5..11).times { FactoryGirl.create(:user) }
Error:
ActiveRecord::RecordInvalid: Validation failed: Email has already been taken
Si abro la consola y uso FactoryGirl.create(:user)
Obtengo los mismos resultados... el mismo objeto se crea una y otra vez aunque si ejecuto solo Faker::Internet.email
varias veces recibiré varios correos electrónicos.
Chica de fábrica:
[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
Farsante por sí mismo:
[3] pry(main)> Faker::Internet.email
=> "hobart_purdy@goodwinmills.org"
[4] pry(main)> Faker::Internet.email
=> "pierce_brekke@gislasonrolfson.net"
¿Que me estoy perdiendo aqui?¿Por qué Faker produce los mismos datos cada vez que se utilizan a través de FactoryGirl?
Solución
Debe pasar un bloque si desea que los valores se vuelvan a evaluar por cada instancia creada.
en lugar de
email Faker::Internet.email
intentar ...
email { Faker::Internet.email }
Otros consejos
Uso de Faker para obtener atributos que pasan singularidad pueden ser un anti-patrón.También puede ser una mala idea tener la salida semieseatoria de Faker en las pruebas, ¿qué pasa si a veces las pruebas simplemente fallan y usted está fuera de una persecución de ganso salvaje, solo porque Faker tosió un valor que no esperaba?
últimamente he estado usando las secuencias de FactoryGirl para obtener valores predecibles, sin embargo, pasando por la singularidad.
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"
Tomado de Fábrica Girl Tips @ http://arjanvandegaag.nl/blog/factory_girl_tips.html