简体   繁体   中英

FactoryGirl: has_many :through, validates_presence_of: association error: can't be blank?

I'm receiving the below test failure on my Article factory, which has a has_many through:, validates_presence_of relationship with my Categories model. The Categories need to exist before the Article is created, so I've set up a before(:create), create_list hook to create and associate some categories with the article being created, but I'm receiving the below failure. I've also tried using association (eg association :categories, factory: :category), but based on what I've read, the relationships that my models have (have_many :through), requires I use the before(:create) hooks. What am I missing?

Failures:

  1) Factory Girl article factory is valid
     **Failure/Error: expect(factory).to be_valid, lambda { factory.errors.full_messages.join("\n") }
       Categories can't be blank**
     # ./spec/support/factories_spec.rb:17:in `block (4 levels) in <top (required)>'

Models

class User < ActiveRecord::Base
   ...
   has_many :articles
   ...
end

class Article < ActiveRecord::Base
  belongs_to :user

  has_many :article_categories
  has_many :categories, through: :article_categories

  validates_presence_of :categories
  ...
end

class Category < ActiveRecord::Base
  has_many :article_categories
  has_many :articles, through: :article_categories
  ...
end

class ArticleCategory < ActiveRecord::Base
  attr_accessor :article_id, :category_id

  belongs_to :article 
  belongs_to :category
end

Factories

FactoryGirl.define do
  factory :user do
    name { Faker::Name.name }
    email { Faker::Internet.email }
    password 'GoodP@ssw0rd'
    password_confirmation 'GoodP@ssw0rd'
    user_name { Faker.bothify('??????????###') }

    after(:create) do |user, evaluator|
      create_list(:article, rand(1..3), user: user)
    end
  end
end

FactoryGirl.define do
  factory :article do
    title { Faker::Lorem.paragraph[0..(rand(11..63))] }
    content { Faker::Lorem.paragraph[0..(rand(150..5000))] }

    before(:create) do |article, evaluator|
      create_list(:category, rand(1..3), article: article)
    end
  end
end

FactoryGirl.define do
  factory :category do
    name { Faker::Lorem.characters(10) }
  end
end

FactoryGirl.define do
  factory :article_category do
  end
end

Does this work?

FactoryGirl.define do
  factory :article do
    title { Faker::Lorem.paragraph[0..(rand(11..63))] }
    content { Faker::Lorem.paragraph[0..(rand(150..5000))] }
    categories { create_list(:category, rand(1..3)) }
  end
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM