Faker đang tạo ra dữ liệu trùng lặp khi được sử dụng trong factory_girl


86

Tôi đang cố gắng đưa một số dữ liệu giả vào một nhà máy bằng cách sử dụng đá quý Faker:

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

Tuy nhiên, mặc dù tôi hy vọng điều này sẽ tạo ra những người dùng có tên_người_đầu và tên_các_đầu khác nhau, nhưng mỗi người đều giống nhau:

>> 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">

Làm cách nào để lấy Faker gem để tạo tên mới cho từng người dùng chứ không chỉ sử dụng lại những tên ban đầu?


1
Chỉ là một cảnh quay trong bóng tối, nhưng bạn đã thử sử dụng thứ gì đó như thế user.sequence(:first_name} {|n| Faker::Name::first_name}nào chưa? FactoryGirl có khả năng chỉ đánh giá cuộc gọi Faker của bạn khi nó tải "đồ đạc" của bạn. Sử dụng sequence param,&blockphương pháp nên ngăn chặn điều đó.
Steven

Câu trả lời:


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

Hãy thử đặt dấu ngoặc quanh những người thợ làm bánh. xem liên kết này


8
Tôi yêu stackoverflow rất nhiều - cảm ơn bạn Will, bạn lưu bacon của tôi
Peter Nixey

Cảm ơn bạn, điều này đã khắc phục sự cố của tôi!
Oranges 13

5
Tại sao, tại sao, tại sao? Chuyện gì đang xảy ra ở đây?
jordanpg

4
vì "thuộc tính lười biếng", hãy xem: github.com/thoughtbot/factory_girl/blob/master/…
Siwei Shen 申思维

9
Đáng buồn thay, điều này không phải lúc nào cũng hiệu quả. Về cơ bản điều này chỉ nhận được một đối tượng faker ngẫu nhiên mới, tuy nhiên vì RNG, vẫn có khả năng điều này không thành công.
Michael Lynch

45

Lưu ý rằng Faker vẫn có thể cung cấp dữ liệu trùng lặp do số lượng dữ liệu giả có sẵn có hạn.

Đối với các mục đích thử nghiệm đơn giản và để xác nhận tính duy nhất, tôi đã sử dụng những điều sau:

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

3
Câu trả lời này xứng đáng nhận được nhiều ủng hộ hơn. Nó có khả năng xảy ra khi thử nghiệm của bạn tạo ra nhiều trường hợp.
Enrico Carlesso

Yup, tôi đồng ý với Enrico. +1
karlingen

Ý tưởng hay, nhưng việc thêm dấu ngoặc đơn có thể phá vỡ phần còn lại nếu bạn sử dụng tên và họ để tạo email hoặc bạn có xác thực về định dạng (không biết bất kỳ tên nào có dấu ngoặc đơn: P).
Cyril Duchon-Doris

18

Vì lợi ích của việc duy trì câu trả lời chính xác, ở đây nó được chuyển từ blog, tôi không có tín dụng cho câu trả lời.

Nếu bạn sử dụng mã dưới đây, faker sẽ không tạo ra những cái tên duy nhất

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

Tuy nhiên, đặt dấu ngoặc nhọn xung quanh faker làm cho nó hoạt động!

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

Để giải thích tại sao, ví dụ đầu tiên là tạo ra những cái tên giống nhau. Nó chỉ đánh giá một lần. Ví dụ thứ hai đánh giá mỗi khi nhà máy được sử dụng.

Điều này là do {}đánh giá lười biếng cung cấp. Về cơ bản, họ đang cung cấp một proc / lambda với lệnh gọi Faker làm giá trị trả về của họ.


Cảm ơn vì đã đăng tải điều này. Tôi không thể hiểu tại sao Faker không thể tạo dữ liệu ngẫu nhiên và có vẻ như mọi ví dụ tôi đã xem đều cho thấy cách sử dụng trình tự có vẻ kỳ lạ đối với tôi. Tôi muốn sử dụng Faker nên mỗi bản ghi là ngẫu nhiên, không theo trình tự. Chỉ cần thêm dấu ngoặc nhọn xung quanh các cuộc gọi Faker của tôi đã giải quyết được vấn đề. Đơn giản và thanh lịch!
Blimey85

5

Một giải pháp thay thế (kém hiệu quả hơn) cho việc sử dụng chuỗi khi bạn có xác thực tính duy nhất trên một thuộc tính là kiểm tra xem giá trị được đề xuất đã tồn tại hay chưa và tiếp tục thử các giá trị mới cho đến khi nó là duy nhất:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.