FactoryBot последовательность с параметром - PullRequest
0 голосов
/ 28 декабря 2018

Я хочу иметь возможность увеличивать различные коды одним и тем же способом.Например:

  • Если код 1234: 1234, 1234A, 1234B, ...
  • Если код 5678: 5678, 5678A, 5678B, ...

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

# Not ideal
FactoryBot.define do
  sequence(:1234, "A") { |n| "1234" + n }
  sequence(:5678, "A") { |n| "5678" + n }
end

Я пытался использовать фабрику, которая вызывает последовательность, но я не могу найти никаких примеров использования фабрики, которая создает строку.

FactoryBot.define do
  sequence(:letter, "A") { |n| n }

  factory :violation_code, :class => "String" do
    transient do
      code { "" }
    end
    base_code { code + generate(:letter) }
  end
end

build(:violation_code, :code => "1234")

Я получаю эту ошибку NoMethodError: undefined method 'base_code=' for "":String.

Требования:

  • Генерирует строку с кодом и увеличенной буквой.

Было бы неплохо:

  • Пропускает первую итерацию, поэтому он возвращает только код при первом вызове generate().
  • Когда он достигает Z, он хотел бы перейти на AA вместо A.

1 Ответ

0 голосов
/ 28 декабря 2018

Мне не нужно создавать отдельную последовательность для каждого кода

Это, очевидно, невозможно, поскольку FactoryBot хранит итератор и вызывает #next под капотом.Вы не можете разделить итератор между последовательностями.

Что вы можете сделать, вы можете начать непосредственно с "1234A":

"1234A".next
#⇒ "1234B"

К сожалению, он переходит на "1235A" с "1234Z".Но "Z".next производит "AA".Итак, оберните FactoryBot::DefinitionProxy#sequence в:

FactoryBot::DefinitionProxy.prepend(Module.new do
  def sequence(name, *args, &block)
    if args.last.is_a?(Hash) && prefix = args.last.delete(:prefix)
      super(name, *args) { |n| prefix + n }
    else
      super
    end
  end
end)

и назовите его следующим образом:

FactoryBot.define do
  sequence("A", prefix: "1234")
end

Я не проверял его, и он, безусловно, может быть значительно улучшен, но идея должнабудь ясен.

...