Faker สร้างข้อมูลซ้ำเมื่อใช้ใน factory_girl


86

ฉันพยายามเติมข้อมูลปลอมในโรงงานโดยใช้ Faker gem:

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

อย่างไรก็ตามในขณะที่ฉันคาดว่าสิ่งนี้จะสร้างผู้ใช้ที่มี first_name และ last_names ต่างกัน แต่แต่ละคนก็เหมือนกัน:

>> Factory(:user)
=> #<User id: 16, email: "user7@blow.com", 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: "user8@blow.com", created_at: "2011-03-18 18:29:39", 
updated_at: "2011-03-18 18:29:39", first_name: "Bailey", last_name: "Durgan">

ฉันจะทำให้ Faker gem สร้างชื่อใหม่สำหรับผู้ใช้แต่ละคนได้อย่างไรและไม่เพียง แต่นำชื่อเดิมมาใช้


1
แค่ถ่ายในที่มืด แต่คุณเคยลองใช้อะไรuser.sequence(:first_name} {|n| Faker::Name::first_name}บ้างไหม? FactoryGirl มีแนวโน้มที่จะประเมินการโทร Faker ของคุณเมื่อโหลด "การแข่งขัน" ของคุณ การใช้sequence param,&blockวิธีควรป้องกันนั้น
Steven

คำตอบ:


156
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

ลองใส่วงเล็บรอบ ๆ fakers ดูลิงค์นี้


8
ฉันชอบ stackoverflow มาก - ขอบคุณวิลคุณช่วยเบคอนของฉัน
Peter Nixey

ขอบคุณสิ่งนี้ช่วยแก้ปัญหาของฉันได้!
Oranges13

5
ทำไมทำไมทำไม? เกิดขึ้นที่นี่คืออะไร?
jordanpg

4
เนื่องจาก "lazy attribute" โปรดดูที่github.com/thoughtbot/factory_girl/blob/master/…
Siwei Shen 申思维

10
น่าเศร้าที่สิ่งนี้ไม่ได้ผลเสมอไป โดยพื้นฐานแล้วสิ่งนี้จะได้รับวัตถุ faker แบบสุ่มใหม่อย่างไรก็ตามเนื่องจาก RNG ยังมีโอกาสที่จะล้มเหลว
Michael Lynch

46

โปรดทราบว่า Faker อาจยังคงให้ข้อมูลที่ซ้ำกันเนื่องจากข้อมูลปลอมมีอยู่จำนวน จำกัด

เพื่อวัตถุประสงค์ในการทดสอบอย่างง่ายและเพื่อให้ได้มาซึ่งการตรวจสอบความเป็นเอกลักษณ์ฉันใช้สิ่งต่อไปนี้

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

3
คำตอบนี้สมควรได้รับการโหวตมากขึ้น มีแนวโน้มที่จะเกิดขึ้นเมื่อการทดสอบของคุณสร้างอินสแตนซ์จำนวนมาก
Enrico Carlesso

ใช่ฉันเห็นด้วยกับ Enrico +1
karlingen

เป็นความคิดที่ดี แต่การเพิ่มวงเล็บอาจทำลายส่วนที่เหลือได้หากคุณใช้ชื่อและนามสกุลในการสร้างอีเมลหรือคุณมีการตรวจสอบความถูกต้องของรูปแบบ (ไม่ทราบชื่อใด ๆ ที่มีวงเล็บ: P)
Cyril Duchon-Doris

18

เพื่อเป็นการรักษาคำตอบที่ถูกต้องนี่คือการแปลจากบล็อกฉันไม่ให้เครดิตสำหรับคำตอบ

หากคุณใช้รหัสด้านล่าง faker จะไม่เปลี่ยนชื่อที่ไม่ซ้ำกัน

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

อย่างไรก็ตามการใส่วงเล็บปีกการอบ ๆ faker ทำให้มันได้ผล!

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

เพื่ออธิบายว่าเหตุใดตัวอย่างแรกจึงสร้างชื่อเดียวกัน เป็นการประเมินเพียงครั้งเดียว ตัวอย่างที่สองประเมินทุกครั้งที่ใช้โรงงาน

เนื่องจาก{}การประเมินที่ขี้เกียจ โดยพื้นฐานแล้วพวกเขากำลังให้ proc / lambda พร้อมกับการเรียก Faker เป็นมูลค่าส่งคืน


ขอขอบคุณสำหรับการโพสต์นี้. ฉันคิดไม่ออกว่าทำไม Faker ไม่สามารถสร้างข้อมูลแบบสุ่มได้และดูเหมือนว่าทุกตัวอย่างที่ฉันเจอจะแสดงวิธีใช้การจัดลำดับซึ่งดูแปลกสำหรับฉัน ฉันต้องการใช้ Faker เพื่อให้แต่ละระเบียนเป็นแบบสุ่มไม่เรียงตามลำดับ เพียงแค่เพิ่มวงเล็บปีกการอบ ๆ สาย Faker ของฉันก็แก้ปัญหาได้แล้ว เรียบง่ายและสง่างาม!
Blimey85

5

ทางเลือกที่ (มีประสิทธิภาพน้อยกว่า) ในการใช้ลำดับเมื่อคุณมีการตรวจสอบความไม่ซ้ำกันในแอตทริบิวต์คือการตรวจสอบว่ามีค่าที่เสนออยู่แล้วหรือไม่และลองใช้ใหม่ต่อไปจนกว่าจะไม่ซ้ำกัน:

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.