Машинист, как мне сослаться на объект, который я делаю, и передать его ассоциации? (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 для получения дополнительной информации.