2
votes

I have these two models

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

  has_many :posts
end

class Post < ApplicationRecord
  belongs_to :user
end

These are my factories

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

When I run the following tests I get the following error:

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)

How can I fix this?

This is also my db schema

  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
2

2 Answers

2
votes

I found the solution eventually. The key was missing was the 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
-1
votes

Try the following:

belongs_to :user, optional: true

4.1.2.11 :optional

If you set the :optional option to true, then the presence of the associated object won't be validated. By default, this option is set to false.

You may refer to the docs for more information.