Faker производит дубликаты данных при использовании в factory girl


Я пытаюсь заполнить некоторые поддельные данные на заводе с помощью 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 генерировать новые имена для каждого пользователя, а не просто повторно использовать оригинальные?

4 85

4 ответа:

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

попробуйте поставить скобки вокруг фейкеров. смотрите этой ссылке

обратите внимание, что Faker все еще может предоставлять дубликаты данных из-за ограниченного количества поддельных данных.

для простых целей тестирования и получения валидаций уникальности я использовал следующее:

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

ради сохранения правильного ответа, здесь он транслоцирован из блога, я не беру на себя ответственность за ответ.

Если вы используете код ниже, faker не будет штамповать уникальные имена

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

однако положить фигурные скобки вокруг Факер делает его работу!

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

чтобы объяснить, почему, первый пример производит те же имена. Это только оценка один раз. Второй пример оценивает каждый раз, когда используемые на заводе-это.

Это связано с {} обеспечение ленивости. По сути, они предоставляют proc/lambda с вызовом Faker в качестве их возвращаемого значения.

(менее эффективная) альтернатива использованию последовательностей при проверке уникальности атрибута заключается в том, чтобы проверить, существует ли уже предлагаемое значение и продолжать пробовать новые, пока оно не станет уникальным:

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