FactoryGirl + Falsificador - mesmos dados a ser gerado para cada objeto no banco de sementes de dados
-
26-12-2019 - |
Pergunta
Eu estou usando FactoryGirl e Falsificador para gerar objetos de usuário no meu seeds.rb
arquivo, mas por algum motivo, o exato mesmo usuário que está sendo criado e rake db:seed
está a falhar por causa de um e-mail de exclusividade de validação.
Fábrica para os usuários:
#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
E o código de seeds.rb
arquivo:
#seeds.rb
rand(5..11).times { FactoryGirl.create(:user) }
Erro:
ActiveRecord::RecordInvalid: Validation failed: Email has already been taken
Se eu abrir o console e usar FactoryGirl.create(:user)
Eu obter os mesmos resultados...mesmo objeto que está sendo criado mais e mais, mesmo que se eu ficar só Faker::Internet.email
várias vezes eu vou ter vários endereços de 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 por si só:
[3] pry(main)> Faker::Internet.email
=> "hobart_purdy@goodwinmills.org"
[4] pry(main)> Faker::Internet.email
=> "pierce_brekke@gislasonrolfson.net"
O que estou ausente aqui?Por que é Faker produzir os mesmos dados de cada vez, quando utilizado através de FactoryGirl?
Solução
Você precisa passar um bloco que se deseja os valores re-avaliadas para cada instância criada.
Em vez de
email Faker::Internet.email
tente...
email { Faker::Internet.email }
Outras dicas
Usando o Falsificador para obter a exclusividade de passagem de atributos pode ser um anti-padrão.Ele também pode ser uma má idéia ter Falsificador do semi-aleatório de saída em testes - e se, por vezes, os testes só falha e você está fora para um ganso selvagem perseguição apenas porque Falsificador tossiu um valor que você não esperava?
Ultimamente tenho vindo a utilizar FactoryGirl sequências para obter previsível, ainda singularidade de passagem de valores.
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"
Tomadas de Fábrica Menina dicas @ http://arjanvandergaag.nl/blog/factory_girl_tips.html