Rails4项目RSpec测试中FactoryGirl别名关联额外创建Company问题求助
我之前也碰到过类似的FactoryGirl关联坑,这大概率是因为嵌套的billing_batch工厂没有继承Customer的company关联,而是默认新建了一个独立的Company实例。咱们一步步来修复:
1. 先定位问题根源
先检查你的billing_batch工厂定义,是不是默认会自动创建新Company?比如这种写法:
FactoryGirl.define do factory :billing_batch do company # 这里没指定关联来源,会默认新建一个Company # 其他属性... end end
这就是额外生成Company的原因——当Customer工厂创建billing_batch时,billing_batch会自己生成全新的Company,而不是复用Customer的那个。
2. 修改Customer工厂,传递Company给BillingBatch
我们需要让billing_batch明确使用Customer关联的Company,有两种常用写法:
方式一:直接在关联时传递参数
在Customer工厂里定义billing_batch关联时,显式把当前Customer的company传过去:
FactoryGirl.define do factory :customer do company # 其他Customer属性... # 让billing_batch复用当前Customer的company billing_batch { association(:billing_batch, company: company) } end end
这里的company指的是当前Customer实例的company属性,这样billing_batch就会和Customer共享同一个Company,不会额外创建了。
方式二:用回调传递关联
如果你的billing_batch是通过回调(比如after(:build))创建的,可以这样写:
FactoryGirl.define do factory :customer do company # 其他属性... after(:build) do |customer| customer.billing_batch = build(:billing_batch, company: customer.company) end end end
这种方式在构建Customer对象时,就会给billing_batch绑定好同一个Company。
3. 验证修复效果
现在执行create(:customer, company: @company),去数据库里检查billing_batches表的company_id,应该和@company的ID完全一致,而且不会再出现额外生成的Company记录了。
如果你的billing_batch大部分场景都需要关联所属Customer的Company,也可以在billing_batch工厂里设置默认逻辑,但更推荐在Customer工厂里显式传递,这样逻辑更清晰,也避免其他场景出现意外关联。
内容的提问来源于stack exchange,提问作者Dmitry Gusev

