4

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

我有一个 Pressroom 模型,属于 Source,Source 有很多 Pressrooms。创建 Source 时,如果 pressrooms 为空,则会在 after_create 过滤器中创建初始 pressroom。每个来源的新闻发布室站点必须是唯一的。

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而无需在此过程中制作两个新闻发布室。如果切换到工厂女孩会有所帮助,我对此持开放态度。

对于如何解决此问题的任何想法,我将不胜感激。

4

2 回答 2

2

谷歌搜索,我在http://webcrisps.wordpress.com/2009/08/13/stubbing-before_create-callbacks-in-a-machinist-blueprint/上找到了一些提示——after_create :create_initial_pressroom!在 Source 蓝图中存根 Source 上的回调– 在这里使用机械师 2 和摩卡:

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 上接受我自己的答案。

于 2011-03-24T19:01:07.073 回答
1

您使用的是机械师 1 还是 2?这些针对机械师 2 的建议可能适用于机械师 1,也可能不适用。我不记得您在机械师 1 中是如何做到的(也懒得去谷歌了!)。

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

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

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

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

假设您的关联设置正确,那应该可以工作。有关更多信息,请参阅蓝图 wiki 页面

于 2011-03-24T16:57:21.527 回答