【问题标题】:FactoryGirl::InvalidFactoryError: Validation failed: <Class> must exist (ActiveRecord::RecordInvalid)FactoryGirl::InvalidFactoryError:验证失败:<Class> 必须存在 (ActiveRecord::RecordInvalid)
【发布时间】:2017-08-24 21:15:56
【问题描述】:

我有这两个模型

class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  has_many :posts
end

class Post < ApplicationRecord
  belongs_to :user
end

这些是我的工厂

FactoryGirl.define do
  factory :user do
    id 1
    first_name 'John'
    last_name 'Doe'
    sequence(:email) { |n| "tester#{n}@example.com" }
    password 'secretpassword'
  end
end

FactoryGirl.define do
  factory :post do
    user_id 1
    title 'This is a title'
    body 'This is a body'
    published_at Time.now
  end
end

当我运行以下测试时,我收到以下错误:

RSpec.describe User, type: :model do
  let(:user) { build(:user) }
  it { expect(user).to have_many(:posts) }
end

RSpec.describe Post, type: :model do
  let(:post) { build(:post) }
  it { expect(post).to belong_to(:user) }
end

# Error I get:
FactoryGirl::InvalidFactoryError:
  The following factories are invalid:

  * post - Validation failed: User must exist (ActiveRecord::RecordInvalid)

我该如何解决这个问题?

这也是我的数据库架构

  create_table "posts", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.integer  "user_id"
    t.string   "title"
    t.text     "body",         limit: 65535
    t.datetime "published_at"
    t.datetime "created_at",                 null: false
    t.datetime "updated_at",                 null: false
    t.index ["user_id"], name: "index_posts_on_user_id", using: :btree
  end

create_table "users", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
  # Whatever devise generates
end

【问题讨论】:

    标签: ruby-on-rails rspec tdd shoulda


    【解决方案1】:

    我最终找到了解决方案。缺少的关键是association :user

    FactoryGirl.define do
      factory :post do
        title 'This is a title'
        body 'This is a body'
        published_at Time.now
        association :user
      end
    end
    

    【讨论】:

      【解决方案2】:

      尝试以下方法:

      belongs_to :user, optional: true
      

      4.1.2.11:可选

      如果您将 :optional 选项设置为 true,则存在 关联对象不会被验证。默认情况下,此选项已设置 为假。

      您可以参考docs了解更多信息。

      【讨论】:

      • 我已经尝试过了,但又遇到了另一个错误:* post - Mysql2::Error: Cannot add or update a child row: a foreign key constraint fails
      • @Lykos 如果子表包含一些具有外键但不在父表中的数据,则会发生这种情况。在您的情况下,post.user_iduser.id 的外键,并且发布表包含 user_id 用户表中不存在。
      • 不确定我是否明白你在说什么,但我生成了这个迁移是为了关联帖子-用户add_reference :posts, :user, foreign_key: true, after: :id这就是我设置post.user_id的方式
      • 等等,这个问题是不是因为我在测试中使用build而不是create??
      • @Lykos create() 方法保留模型的实例,而 build() 方法仅将其保留在内存中,因此这可能是孤儿记录的原因。无论如何,你应该清理你的测试数据库。
      猜你喜欢
      • 2020-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多