我正在尝试为相对复杂的模型建造工厂。
我有一个新闻室模型,属于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
干净地制作印刷车间而不需要在这个过程中建立两个印刷车间。如果转向工厂女孩会有所帮助,我对此持开放态度。
我很感激有关如何解决这个问题的任何想法。
答案 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。