【问题标题】:FactoryGirl: has_many :through, validates_presence_of: association error: can't be blank?FactoryGirl: has_many :through, validates_presence_of: 关联错误:不能为空?
【发布时间】:2014-09-30 02:59:04
【问题描述】:

我的 Article 工厂收到以下测试失败,该工厂与我的 Categories 模型有 has_many through:, validates_presence_of 关系。类别需要在创建文章之前存在,因此我设置了一个 before(:create)、create_list 挂钩来创建一些类别并将其与正在创建的文章相关联,但我收到以下失败。我也尝试过使用 association(例如 Association :categories, factory: :category),但根据我所阅读的内容,我的模型所具有的关系(have_many :through)需要我使用before(:create) 钩子。我错过了什么?

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)>'

模型

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

工厂

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

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4 factory-bot rspec-rails rspec3


    【解决方案1】:

    这行得通吗?

    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
    

    【讨论】:

    • 啊,也许before(:create) 验证发生后运行。我修改了上面的答案。现在运气好吗?
    • 做到了;没有办法使用之前(:xxx)来做到这一点?如果我想使用瞬态属性怎么办?非常感谢:)
    • 好问题。也许after(:build) 钩子会在验证之前运行?
    猜你喜欢
    • 2018-09-02
    • 1970-01-01
    • 2013-08-20
    • 1970-01-01
    • 2015-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多