Машинист, как мне сослаться на объект, который я делаю, и передать его ассоциации? (AssociationTypeMismatch)

Я пытаюсь построить фабрики для относительно сложных моделей.

У меня есть модель Пресс-зала, которая принадлежит Источнику, а у Источника много Пресс-румов. При создании источника, если пресс-залы пустые, в фильтре after_create создается начальный пресс-центр. Сайт пресс-центра должен быть уникальным для каждого источника.

class Source
  has_many :pressrooms
  after_create :create_initial_pressroom! # if pressrooms.empty?
  ...
end

class Pressroom
  belongs_to :source
  # source.pressrooms.map(&:site) should have unique elements
  validate_on_create :check_unique_site
end

Это приводит к моей проблеме: мой Pressroom.make не удается, потому что он создает источник, который не имеет пресс-залов, поэтому after_create обратный вызов создает один, и когда Pressroom.make пытается закончить, его сайт не уникален. Я не хочу создавать две пресс-комнаты, когда я бегу Pressroom.make

Моя попытка решить эту проблему - сделать так, чтобы источник связи в проекте пресс-центра ссылался на пресс-центр. Вроде что Source.create :pressrooms => [Pressroom.new] сделал бы.

Pressroom.blueprint do
  source { Source.make :pressrooms => [self] }
  site { source.site }
end

Unfortunatly, self еще не пресс-центр. Это экземпляр Machinist::Lathe, поэтому я получаю исключение ActiveRecord::AssociationTypeMismatch.

Я немного новичок, когда дело доходит до фабрик и машинистов. Я не хочу менять бизнес-логику, и я хочу быть в состоянии создать пресс-центр с Pressroom.make без создания двух пресс-центров в процессе. Если переход на заводскую девушку поможет, я открыт для этого.

Буду признателен за любые идеи, как решить эту проблему.

2 ответа

Погуглив, я нашел несколько подсказок на http://webcrisps.wordpress.com/2009/08/13/stubbing-before_create-callbacks-in-a-machinist-blueprint/ - чтобы заглушить after_create :create_initial_pressroom! обратный вызов источника, в схеме источника - с использованием Machinist 2 и Mocha здесь:

Pressroom.blueprint do
  source { Source.make!(:without_initial_pressroom) }
  site   { object.source.site }
end

Source.blueprint do
  site
end

Source.blueprint(:without_initial_pressroom) do
  object.stubs(:create_initial_pressroom!).returns(true)
end

Сюда, Pressroom.make! работает как надо, Source.make! работает так, как должно, и... думаю, я счастлив. Но все еще немного озадачен проблемами, с которыми я столкнулся в решении, которое я попробовал выше (как в машинисте 1, так и в 2).

Если кто-нибудь знает, как заставить это работать с object, дай мне знать. Это было бы намного чище, и, кроме того, я вообще не люблю принимать свои собственные ответы здесь на stackru.

Вы используете Машинист 1 или 2? Эти предложения для Machinist 2 и могут работать, а могут и не работать в Machinist 1. Я не могу вспомнить, как вы делаете это в Machinist 1 (и не можете быть обеспокоены Google!).

Чтобы сделать это так, как вы предлагаете, вам нужно использовать object:

Pressroom.blueprint do
  source { Source.make :pressrooms => [object] }
  site { source.site }
end

Но гораздо более приятный способ сделать это - воспользоваться тем фактом, что Machinst знает об ассоциациях моделей, и просто позволить ему сделать свое дело:

Pressroom.blueprint do
  source
  site { source.site }
end

Предполагая, что ваши ассоциации настроены правильно, это должно работать. См. Вики-страницу Blueprints для получения дополнительной информации.

Другие вопросы по тегам