FactoryBot - переопределить ассоциацию с чертой - PullRequest
0 голосов
/ 05 июня 2018

Скажем, у меня есть пара моделей, sport и player, из которых игрок belongs_to sport и sport has_many player.Затем я создаю фабрики для обоих из них следующим образом:

FactoryBot.define do
  factory :player do
    name "John Doe"
    sport

    trait :with_existing_sport do
      transient do
        sport Sport.last
      end

      sport { with_existing_sport }
    end
  end
end

FactoryBot.define do
  factory :sport do
    name "football"
  end
end

Когда я открываю консоль rails и запускаю FactoryBot.create(:player), она отлично работает и создает нового игрока и связанный вид спорта в базе данных.Но когда я запускаю FactoryBot.create(:player, :with_existing_sport), я ожидаю, что он создаст игрока, но затем ассоциирует этого игрока с Sport.last, но вместо этого он возвращает:

FactoryBot::AttributeDefinitionError: Attribute already defined: sport

Итак, в общем, что я пытаюсьДля достижения этой цели необходимо:

  • FactoryBot.create(:player) создать игрока, а спорт
  • FactoryBot.create(:player, :with_existing_sport) создать игрока и сделать его принадлежащим Sport.last
  • FactoryBot.create(:player, with_existing_sport: Sport.first) должен создать игрока и он должен принадлежать Sport.first

Есть ли способ сделать это?Я ничего не могу найти в документации.

* редактировать *

решение

Благодаря Марлину Пирсу, яв итоге получилось так:

FactoryBot.define do
  factory :player do
    name "John Doe"
    sport

    trait :with_existing_sport do
      transient do
        associated_sport Sport.last
      end

      sport { associated_sport }
    end
  end
end

FactoryBot.define do
  factory :sport do
    name "football"
  end
end

Теперь я могу использовать фабрику следующим образом:

  • FactoryBot.create(:player), которая создаст игрока и связанный с ним спорт
  • FactoryBot.create(:player, :with_existing_sport), который создаст игрока и свяжет его с Sport.last
  • FactoryBot.create(:player, :with_existing_sport, associated_sport: Sport.find_by(name: "football")), который свяжет его с associated_sport

1 Ответ

0 голосов
/ 05 июня 2018

Я думаю, что вы хотите:

FactoryBot.define do
  factory :player do
    name "John Doe"
    sport

    trait :with_existing_sport do
      sport { Sport.last }
    end
  end
end

Если вам действительно нужно временное свойство, вы должны переименовать его во что-то отличное от непереходного поля.

trait :with_existing_sport do
  transient do
    sport_trans Sport.last
  end

  sport { sport_trans }
end
...