0

我是 FactoryGirl 的新手(并且是一般测试),我正在尝试为 has_many 关系建立一个工厂。到目前为止,我发现的所有示例都使用了旧版本的工厂女孩​​,官方文档并没有那么有用。

当我运行测试时,它说:

Failures:

  1) Brand has a valid factory
     Failure/Error: FactoryGirl.create(:brand).should be_valid
     ActiveRecord::RecordInvalid:
       Validation failed: Styles can't be blank
     # ./spec/models/brand_spec.rb:5:in `block (2 levels) in <top (required)>'

品牌.rb

class Brand < ActiveRecord::Base
  attr_accessible               :title,
                                :style_ids

  has_many                      :brand_styles, dependent: :destroy
  has_many                      :styles,       through: :brand_styles

  validates_presence_of         :title
  validates_presence_of         :styles
end

样式.rb

class Style < ActiveRecord::Base
  attr_accessible               :title

  has_many                      :brand_styles, dependent: :destroy
  has_many                      :brands,       through: :brand_styles

  validates_presence_of         :title
end

品牌风格.rb

class BrandStyle < ActiveRecord::Base
  attr_accessible :brand_id, 
                  :style_id

  belongs_to      :brand
  belongs_to      :style
end

工厂

FactoryGirl.define do
  factory :brand do
    title "Some Brand"

    after(:create) do |brand| 
      brand.style create(:brand_style, brand:brand, style: FactoryGirl.build(:style))
      brand.reload
    end
  end

  factory :style do
    title "Some Style"
  end

  factory :brand_style do
    brand
    style
  end
end

规格

require 'spec_helper'

describe Brand do
  it "has a valid factory" do
    FactoryGirl.create(:brand).should be_valid
  end
end

- -编辑 - -

我已经按照 Damien Roches 的建议修改了我的工厂,现在出现了这个错误:

Failures:

  1) Brand has a valid factory
     Failure/Error: FactoryGirl.create(:brand).should be_valid
     NoMethodError:
       undefined method `primary_key' for #<FactoryGirl::Declaration::Implicit:0x007fc581b2d178>
     # ./spec/factories/brand.rb:4:in `block (3 levels) in <top (required)>'
     # ./spec/models/brand_spec.rb:5:in `block (2 levels) in <top (required)>'

改装厂

FactoryGirl.define do
  factory :brand do |brand|
    brand.title "Some Brand"
    brand.styles { build_list(:brand_style, 1, brand: brand, style: build(:style)) }
  end

  factory :style do
    title "Some Style"
  end

  factory :brand_style do
    brand
    style
  end
end
4

1 回答 1

0

用这个替换你的after(:create)块:

styles { build_list(:brand_style, 1, brand: brand, style: build(:style)) }

我的factory_girl知识有点粗糙,所以如果您有进一步的麻烦,请告诉我,我会在有机会时回复。

几个笔记。您不能使用after(:create),因为您的brand模型需要styles. 您不能使用brand.style,因为关系是has_many。那应该是brand.styles。有了这个,你不能使用brand.styles = create(),因为赋值需要一个数组。你可以使用brand.styles = [create()],但我更喜欢create_list.

我已经替换create(:brand_style)build. 测试不同的变体,因为我发现有时在您保存父对象时关联不会保存,具体取决于您的配置。有关详细信息,请参见此处

于 2013-10-26T06:31:07.987 回答