vladra
vladra

Reputation: 186

Factory girl has one association

Trying to build has_one association with factory girl with no success.

class User < ActiveRecord::Base
  has_one :profile
  validates :email, uniqueness: true, presence: true
end

class Profile < ActiveRecord::Base
  belongs_to :user, dependent: :destroy, required: true
end

FactoryGirl.define do
  factory :user do
    email '[email protected]'
    password '123456'
    password_confirmation '123456'
    trait :with_profile do
      profile
    end
  end

  create :profile do
    first_name 'First'
    last_name 'Last'
    type 'Consumer'
  end
end

build :user, :with_profile
-> ActiveRecord::RecordInvalid: Validation failed: User can't be blank

If I'm adding user association to profile factory, then additional user is created and saved to DB. So I have 2 users (persisted and new) and 1 profile for persisted user.

What am I doing wrong? Thanks in advance.

Upvotes: 2

Views: 1556

Answers (3)

Nesha Zoric
Nesha Zoric

Reputation: 6620

This is a great way to build your profile and user factory:

FactoryGirl.define do
  factory :user do
    email '[email protected]'
    password '123456'
    password_confirmation '123456'

    factory :user_with_profile do
      after(:create) do |user|
        create(:profile, user: user)
      end
    end
  end
end

When we create a new user with: user = build_stubbed(:user_with_profile), the user profile will be created as well, as well.

This article is a worthwhile read if you want to research more about factory girl associations.

Upvotes: 0

Spyros Mandekis
Spyros Mandekis

Reputation: 1024

A quick workaround that works for me is to wrap the profile creation in an after(:create) block, like this :

FactoryGirl.define do
  factory :user do
    email '[email protected]'
    password '123456'
    password_confirmation '123456'
    trait :with_profile do
      after(:create) do |u|
        u.profile = create(:profile, user: u)
      end
    end
  end

  factory :profile do
    first_name 'First'
    last_name 'Last'
    type 'Consumer'
  end
end

Upvotes: 7

Collin Graves
Collin Graves

Reputation: 2257

FactoryGirl.define do
  factory :user do
    email '[email protected]'
    password '123456'
    password_confirmation '123456'
    trait :with_profile do
      profile { Profile.create! }
    end
  end

  factory :profile do
    first_name 'First'
    last_name 'Last'
    type 'Consumer'
    user
  end
end

Upvotes: 0

Related Questions