Factory Girl:如何防止一些特征的回调函数?

3

我有一个模型类FactoryGirl。在这个模型中,我定义了一些特性。但是在某些特性中,我不想让FactoryGirl回调被调用,但我不知道该怎么做。以下是我的代码示例:

FactoryGirl.define do
  factory :product do
    sequence(:promotion_item_code) { |n| "promotion_item_code#{n}" }

    after :create do |product|
      FactoryGirl.create_list :product_details, 1, :product => product
    end

    trait :special_product do
       # do some thing
       # and don't want to run FactoryGirl callback
    end
end

在这段代码中,我不希望 :special_product 特性在 create 后被调用。我不知道如何做到这一点。
@Edit: 我之所以这样做,是因为有时我想从父对象生成数据到子对象,但有时我想反过来从子对象生成到父对象。因此,当我从子对象回到父对象时,会调用父对象的回调函数,因此子对象会被创建两次。这不是我想要的结果。
@Edit 2: 我的问题是防止 FactoryGirl 的回调函数被调用,而不是 ActiveRecord 模型的回调函数。
谢谢!

可能是跳过Factory Girl和Rspec上的回调的重复问题。 - Wes Foster
1
@WesFoster 不是的。请仔细阅读问题和答案。你的帖子是关于跳过ActiveRecord回调的。 - Trần Kim Dự
2个回答

3
你可���使用“瞬时属性”来实现这一点,与factory_girl相关。

例如:

factory :product do
  transient do
    create_products true
  end

  sequence(:promotion_item_code) { |n| "promotion_item_code#{n}" }

  after :create do |product, evaluator|
    FactoryGirl.create_list(:product_details, 1, :product => product) if evaluator.create_products
  end

  trait :special_product do
     # do some thing
     # and don't want to run FactoryGirl callback
  end
end

但我认为更好的建模方法是为“基本情况”定义一个trait,或者拥有多个工厂。


不行,问题还是一样的,因为create_products总是被设置了。 - Trần Kim Dự
当你不想创建产品时,应将 create_products 设置为 false。 - Fredius
我正在使用关联。我不知道如何传递数据。这是我的代码:association :product, :factory => [:product, :special_product],谢谢。 - Trần Kim Dự
1
我认为 association :product, factory: [:product, :special_product], create_products: false 应该可以工作。更多信息请参见:https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#traits - Fredius
非常感谢。它运行良好 :D 尽管我不能将你的链接(有关特质)映射到你的代码中(使用关联+特质+自定义属性,如瞬时),但你能告诉我更多信息吗?从哪里可以在文档中找到这个?谢谢 :D - Trần Kim Dự
这不是完全相同的例子,但如果您搜索“关联”,您应该会看到它将属性传递给关联,例如name: "John Doe"trait - Fredius

0

对于has_many关系,您可以使用与Factory Girl文档中描述的相同方法:

factory :product_detail do
  product
  #... other product_detail attributes
end

factory :product do
  sequence(:promotion_item_code) { |n| "promotion_item_code#{n}" }

  factory :product_with_details do
    transient do
      details_count 1  # to match your example.
    end

    after(:create) do |product, evaluator|
      create_list(:product_detail, evaluator.details_count, product: product)
    end
  end

  trait :special_product do
    # do some thing
    # and don't want to run FactoryGirl callback
  end
end

这可以让您为父级->子级生成数据:

create(:product_with_details)                   # creates a product with one detail.
create(:product_with_details, details_count: 5) # if you want more than 1 detail.

...而对于特殊产品只需

# does not create any product_details.
create(:product)
create(:product, :special_product)

生成子->父

create(:product_detail)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接