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

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

У меня есть модель пресс-центра, которая принадлежит источнику, а у источника много пресс-залов. При создании источника, если пресс-залы пустые, в фильтре 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

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

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

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

Ответы [ 2 ]

2 голосов
/ 24 марта 2011

Погуглив, я нашел несколько подсказок на http://webcrisps.wordpress.com/2009/08/13/stubbing-before_create-callbacks-in-a-machinist-blueprint/ - чтобы заглушить обратный вызов after_create :create_initial_pressroom! на Source, в схеме Source - используя 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, дайте мне знать. Это было бы намного чище, и, кроме того, я вообще не люблю принимать свои собственные ответы здесь на stackoverflow.

1 голос
/ 24 марта 2011

Используете ли вы Машинист 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

Если ваши ассоциации настроены правильно, должен работать. Подробнее см. на вики-странице .

...