FactoryBot拒绝与协会建立工厂

Posted

技术标签:

【中文标题】FactoryBot拒绝与协会建立工厂【英文标题】:FactoryBot refuses to build factory with associations 【发布时间】:2018-02-22 11:16:44 【问题描述】:

找不到FactoryBot拒绝建立与具有has_and_belongs_to_many关系的同一模型关联的工厂的原因。

产品型号:

class Product < ApplicationRecord
#...
  has_and_belongs_to_many :refs,
    class_name: "Product",
     join_table: :refs,
    foreign_key: :from_id,
    association_foreign_key: :to_id,
    dependent: :destroy
  after_destroy :destroy_inverse_refs
#...
end

参考型号:

class Ref < ActiveRecord::Base
#...
  belongs_to :from, class_name: 'Product', foreign_key: 'from_id'
  has_one :to, class_name: 'Product', foreign_key: 'id', primary_key: 'to_id'
end

工厂:

FactoryBot.define do
  factory :ref do
    association :from, factory: :product
    association :to, factory: :product
  end
end

找不到这个工厂建立的原因:从与 id 的关联和:到没有它的关联:

ref = FactoryBot.build(:ref)

puts ref.inspect
#<Ref id: nil, from_id: 8965, to_id: nil, created_at: nil, updated_at: nil>

puts ref.from.inspect
#<Product id: 8965, category_id: 12167, name_en: "Product name 1">

puts ref.to.inspect
#<Product id: nil, category_id: 12168, name_en: "Product name 2">

【问题讨论】:

【参考方案1】:

仔细阅读https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md#associations后,我只有一个想法。

想象一下

P1 --from-> REF --to-> P2

REF 属于 P1,因此假定 REF.from_id 是必需的。所以很可能FactoryBot 玩得安全,并猜测最好创建from 对象并将其保存在数据库中,这就是ID已经存在的原因。

另一方面,has_one :to 在数据库中创建 P2 可以安全地推迟到保存 ref 之前。

在您的情况下,FactoryBot 的猜测可能不正确,您可能想使用strategy: 选项进行关联。

如果您希望两个 ID 都可用,请尝试 strategy: :create,但不确定它是否会呈现 build(:ref) 本质上的行为类似于 create(:ref)

【讨论】:

刚刚更改 has_one :to, class_name: 'Product', foreign_key: 'id', primary_key: 'to_id' in Ref model to belongs_to :to, class_name: 'Product', foreign_key: 'to_id'工厂开始一切正常。谢谢你的小费!

以上是关于FactoryBot拒绝与协会建立工厂的主要内容,如果未能解决你的问题,请参考以下文章

在 factorybot 中附加 ActiveStorage 文件

在Rails中使用FactoryBot和Rspec的`raise_record_invalid`

工厂机器人创建不正确的数据

有没有办法知道为什么工厂机器人无法保存记录?

创建篇-工厂模式

从FactoryGirl更新到factoryBot会导致NoMethodError