【问题标题】:FactoryGirl + Faker - same data being generated for every object in db seed dataFactoryGirl + Faker - 为数据库种子数据中的每个对象生成相同的数据
【发布时间】:2015-09-21 20:12:11
【问题描述】:

我正在使用 FactoryGirl 和 Faker 在我的 seeds.rb 文件中生成用户对象,但由于某种原因,正在创建完全相同的用户,而 rake db:seed 由于电子邮件唯一性验证而失败。

用户工厂:

#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

还有seeds.rb文件中的代码:

#seeds.rb
rand(5..11).times { FactoryGirl.create(:user) }

错误:

ActiveRecord::RecordInvalid: Validation failed: Email has already been taken

如果我打开控制台并使用FactoryGirl.create(:user),我会得到相同的结果...即使我只运行Faker::Internet.email 多次,我也会收到几封电子邮件。

工厂女孩:

[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 本身:

[3] pry(main)> Faker::Internet.email
=> "hobart_purdy@goodwinmills.org"
[4] pry(main)> Faker::Internet.email
=> "pierce_brekke@gislasonrolfson.net"

我在这里缺少什么?为什么通过 FactoryGirl 使用 Faker 每次都产生相同的数据?

【问题讨论】:

标签: ruby-on-rails database factory-bot seeding faker


【解决方案1】:

如果您希望为每个创建的实例重新评估值,则需要传递一个块。

代替

email   Faker::Internet.email

试试……

email   { Faker::Internet.email }

【讨论】:

    【解决方案2】:

    使用 Faker 获取唯一性传递属性可能是一种反模式。在测试中使用 Faker 的半随机输出也可能是个坏主意 - 如果有时测试只是失败了,而你只是因为 Faker 咳出了一个你没想到的值而大发雷霆怎么办?

    最近我一直在使用 FactoryGirl 的序列来获得可预测但传递唯一性的值。

    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"
    

    取自工厂女孩提示@http://arjanvandergaag.nl/blog/factory_girl_tips.html

    【讨论】:

      猜你喜欢
      • 2015-02-14
      • 1970-01-01
      • 2019-04-29
      • 2018-07-08
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 2016-04-20
      相关资源
      最近更新 更多