FactoryGirl в Rails — Ассоциации с уникальными ограничениями

Этот вопрос является расширением вопроса, поднятого здесь:

Использование factory_girl в Rails с ассоциациями, имеющими уникальные ограничения. Получение повторяющихся ошибок

Предложенный ответ отлично сработал для меня. Вот как это выглядит:

# Creates a class variable for factories that should be only created once.

module FactoryGirl

  class Singleton
    @@singletons = {}

    def self.execute(factory_key)
      begin
        @@singletons[factory_key] = FactoryGirl.create(factory_key)
      rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotUnique
        # already in DB so return nil
      end

      @@singletons[factory_key]
    end
  end

end

Проблема, с которой я столкнулся, заключается в том, что мне нужно вручную создать ассоциацию для поддержки полиморфной ассоциации с ограничением уникальности в ловушке. Например:

class Matchup < ActiveRecord::Base
  belongs_to :event
  belongs_to :matchupable, :polymorphic => true

  validates :event_id, :uniqueness => { :scope => [:matchupable_id, :matchupable_type] }
end

class BaseballMatchup < ActiveRecord::Base
  has_one :matchup, :as => :matchupable
end

FactoryGirl.define do
  factory :matchup do
    event { FactoryGirl::Singleton.execute(:event) }
    matchupable { FactoryGirl::Singleton.execute(:baseball_matchup) }
    home_team_record '10-5'
    away_team_record '9-6'
  end

  factory :baseball_matchup do
    home_pitcher 'Joe Bloe'
    home_pitcher_record '21-0'
    home_pitcher_era 1.92
    home_pitcher_arm 'R'
    away_pitcher 'Jack John'
    away_pitcher_record '0-21'
    away_pitcher_era 9.92
    away_pitcher_arm 'R'
    after_build do |bm|
      bm.matchup = Factory.create(:matchup, :matchupable => bm)
    end
  end
end

Моя текущая реализация синглтона не поддерживает вызов FactoryGirl::Singleton.execute(:matchup, :matchupable => bm), только FactoryGirl::Singleton.execute(: совпадение).

Как бы вы рекомендовали модифицировать фабрику singleton для поддержки такого вызова, как FactoryGirl::Singleton.execute(:matchup, :matchupable => bm)ИЛИ FactoryGirl::Singleton.execute( :matchup)?

Потому что прямо сейчас приведенный выше код будет выдавать ошибку проверки уникальности («Событие уже занято») каждый раз, когда хук запускается на фабрике :baseball_matchup. В конечном счете, именно это необходимо исправить, чтобы в базе данных не было более одного matchup или baseball_matchup.

9
задан Community 23 May 2017 в 02:29
поделиться