Используйте заводскую последовательность для создания уникальных телефонных номеров

Я новичок в TDD, RSpec и фабриках и пытаюсь понять, как проверить уникальность атрибута номера телефона каждого пользователя. Для этого я пытаюсь использовать последовательность в своей пользовательской фабрике. Мне не повезло со следующим:

FactoryGirl.define do
  factory :user do
    number = 123456789
    sequence(:phone_number) {|n| (number + n).to_s }
  end
end

Любые мысли о том, как лучше всего это сделать? Кроме того, какой тест будет иметь смысл для чего-то подобного, где в конечном итоге я хотел бы добавить следующую проверку к пользовательской модели, чтобы пройти такой тест?

validates :phone_number, :uniqueness => true

Спасибо!


person dougiebuckets    schedule 13.09.2013    source источник


Ответы (4)


Попробуйте использовать лямбду со случайным 10-значным числом:

phone_number { rand(10**9..10**10) } 
person candiman    schedule 15.09.2013
comment
Это не гарантирует, что вы получите уникальный номер телефона. Конечно, это маловероятно, но в любом случае лучше использовать последовательности, как указал drekyau. - person Sean; 13.10.2016

Попробуй это:

FactoryGirl.define do
  sequence :phone_number do |n|
     "123456789#{n}"
  end

  factory :user do
    phone_number
  end
end

и для проверки вашей проверки используйте это в своем user_spec

it { should validate_uniqueness_of(:phone_number) }
person derekyau    schedule 13.09.2013
comment
1. validate_uniqueness_of это метод гема "сопоставление должностей". 2. помните, что вы должны создать запись в этой таблице перед таким тестом (rubydoc.info/github/thoughtbot/shoulda-matchers/master/Shoulda/) - person gotva; 14.09.2013
comment
Спасибо, @gotva совершенно прав, что это нужно, и что вы должны убедиться, что включили их. Однако вам не нужна запись БД для запуска этого сопоставителя, поскольку он просто проверяет, что в вашей модели по существу правильные строки. - person derekyau; 14.09.2013
comment
Спасибо, парни. Я добавил «сопоставители». Хотя, когда я действительно добавляю проверку к модели (т.е. «проверяет: номер_телефона,: уникальность => true»), тест все равно не проходит. Какие-нибудь мысли? - person dougiebuckets; 14.09.2013
comment
можете ли вы вставить какой-нибудь код, который у вас есть в вашей модели/user_spec? возможно суть - person derekyau; 14.09.2013
comment
Конечно вещь. Я должен отметить, что добавление проверки уникальности фактически приводит к сбою всех моих тестов. Вот: gist.github.com/dougiebuckets/6556159 - person dougiebuckets; 14.09.2013
comment
Отказ/ошибка: это {должно быть validate_uniqueness_of(:phone_number)} NoMethodError: неопределенный метод `first' для String:Class - person dougiebuckets; 14.09.2013
comment
странно ... не могли бы вы 1) убедиться, что должны быть установлены совпадения (перезапустить защиту), а также что вызывает «первую» проблему? Могу я увидеть вашу фабрику? Если вы удалите все в user_spec, кроме совпадения shoulda, это сработает? - person derekyau; 14.09.2013
comment
Я могу подтвердить, что должны-сопоставители установлены и перезапустили защиту. Насчет "первого" вопроса, не знаю? Это что-то от shoulda-matcher? Если я удалю все, кроме «это {должно проверить_уникальность_оф (: телефонный_номер) }», я все еще получаю сообщение об ошибке. 'Вот фабрика: gist.github.com/dougiebuckets/6556518 Я очень ценю вашу помощь. - person dougiebuckets; 14.09.2013
comment
попробуйте переместить последовательность за пределы блока factory:user, как я обновил в своем ответе выше. - person derekyau; 14.09.2013
comment
Спасибо. Попробовал это, и я все еще получаю этот странный «неопределенный метод «сначала» для String: Class» - person dougiebuckets; 14.09.2013
comment
Согласно документации shoulda-matchers пытается создать запись в таблицах users без проверки User.new.save(validation => false) и это может быть источником проблемы. Я предлагаю 1. Попробуйте повторить этот код (User.new.save...) в своей консоли - у вас такая же ошибка? 2. попробуйте прочитать стек ошибки в тестах - обычно он сообщает о том, где в вашем апп возникла проблема. 3. создать запись в БД самостоятельно gist.github.com/gotva/6565446 - person gotva; 15.09.2013
comment
Если вам важна длина телефонного номера, это решение не будет работать, когда порядковый номер выходит за пределы однозначных цифр. - person Toby 1 Kenobi; 24.09.2018

Чтобы завершить ответ @westonplatter, чтобы начать с 0 000 000 000, вы можете использовать Строка#rjust:

FactoryGirl.define do
  factory :user do
    sequence(:phone_number) {|n| n.to_s.rjust(10, '0') }
  end
end

Пример:

> 10.times { |n| puts n.to_s.rjust(10, '0') }
0000000000
0000000001
0000000002
0000000003
0000000004
0000000005
0000000006
0000000007
0000000008
0000000009
person mdemolin    schedule 06.07.2017

Хотя случайное решение работает, у вас есть небольшой шанс не получить уникальный номер. Я думаю, вам следует использовать FactoryGirl sequence.

Мы можем начать с 1 000 000 000 (100-000-000) и увеличивать число. Примечание. Это дает вам только 98 999 999 999 уникальных телефонных номеров, которых должно быть достаточно. Если нет, у вас другие проблемы.

FactoryGirl.define do
  sequence :phone_number do |n|
    num = 1*(10**8) + n
    num.to_s
  end

  factory :user do
    phone_number
  end
end
person westonplatter    schedule 21.04.2014