Arel
Arel

Reputation: 3938

Change an attribute on a Factory after creation of record

Using FactoryBot, I'm having trouble creating a admin Factory in my specs because every user is assigned a default role of user in a before_create callback. This means that any role I assign a factory will be changed to user when the callback happens.

What I really want to do is something like this:

Inside my spec

admin = FactoryBot.create(:user)
admin.role = 'admin'

The second line, admin.role = 'admin' doesn't do anything. Any ideas?

I'm open to better ways of doing this as well.

Upvotes: 4

Views: 6836

Answers (4)

Daniel James
Daniel James

Reputation: 401

Instead of admin.role = 'admin', maybe you can try using update_column method. Example:

admin = FactoryBot.create(:user)
admin.update_column(:role, 'admin')

This solution worked for me.

Upvotes: 0

coreyward
coreyward

Reputation: 80138

There might be a way of reassigning the value to a FactoryBot (formerly FactoryGirl) instantiation, but RSpec negates the need:

describe User do
  let(:user) { FactoryBot.create(:user) }

  context 'when admin' do
    let(:user) { FactoryBot.create(:user, admin: true) }

    # ...
  end
end

Upvotes: 5

MrYoshiji
MrYoshiji

Reputation: 54902

Try using a trait:

factory :user do
  sequence(:username) { |n| "User ##{n}"}
  role 'user'  

  trait :is_admin do
    role 'admin'
  end
end

Usage:

FactoryBot.create(:user, :is_admin)

Or eventually an after(:create):

factory :user do
  sequence(:username) { |n| "user ##{n}"}
  role 'user'  
end

factory :user_admin, class: User do
  after(:create) { |user| user.role = 'admin'; user.save } # don't know if the .save is necessary here
  sequence(:username) { |n| "User Admin ##{n}"}
end

Upvotes: 4

Billy Chan
Billy Chan

Reputation: 24815

Just another way

# Steal some code from MrYoshiji at first.
factory :user do
  sequence(:username) { |n| "User ##{n}"}
  role 'user'  

  # Then a separate factory inside
  factory :admin do
    role 'admin'
  end
end

# Use
FactoryBot.create(:admin)

Upvotes: 3

Related Questions