机械师,如何引用我正在制作的对象并将其传递给关联? (AssociationTypeMismatch)

时间:2011-03-24 16:27:01

标签: ruby-on-rails ruby factory-bot machinist

我正在尝试为相对复杂的模型建造工厂。

我有一个新闻室模型,属于Source,Source有很多新闻室。创建源时,如果印刷车间为空,则会在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失败了,因为它构建了一个没有新闻发布室的Source,因此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 个答案:

答案 0 :(得分:2)

谷歌搜索,我在http://webcrisps.wordpress.com/2009/08/13/stubbing-before_create-callbacks-in-a-machinist-blueprint/上找到了一些提示 - 在Source蓝图中存根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进行此操作,请告诉我们。它会更清洁,而且我通常不喜欢在stackoverflow上接受我自己的答案。

答案 1 :(得分:1)

您使用机械师1或2吗?这些对Machinist 2的建议可能也可能不适用于Machinist 1.我不记得你是如何在机械师1中做到这一点的(并且不会被谷歌打扰!)。

要按照您的建议方式执行此操作,您需要使用object

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

但更好的方法是利用Machinst了解模型关联的事实,让它做它的事情:

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

假设您的关联设置正确,应该工作。有关详情,请参阅Blueprints wiki page