Chris V. February 2016

"Name has already been taken" in RSpec/FactoryGirl with multiple associations

I am trying to run a very basic spec test and it fails with the error "Name has already been taken".

Update belongs to User who has many Roles.

user model

# == Schema Information
#
# Table name: users
#
#  id                     :integer          not null, primary key
#  email                  :string           default(""), not null
#

FactoryGirl.define do
  factory :user_engineer, class: User do
    id 1
    email 'someone@somewhere.com'
    roles {[FactoryGirl.create(:engineer)]}
  end
end

roles model

# == Schema Information
#
# Table name: roles
#
#  id          :integer          not null, primary key
#  name        :string
#  description :text
#

FactoryGirl.define do
  factory :engineer, class: Role do
    id 3
    name 'Engineer'
    description 'He is the chosen one'
  end
end

updates model

# == Schema Information
#
# Table name: updates
#
#  id            :integer          not null, primary key
#  content       :text
#  user_id       :integer
#  ticket_id :integer
#

FactoryGirl.define do
  factory :update do
    content "This is a test update"
    association :user, factory: :user_engineer
  end
end

update_spec.rb

require 'rails_helper'

RSpec.describe Update, type: :model do
  let(:update){ FactoryGirl.create :update }
  it { expect(update).to be_valid }
end

This is the error:

Update
  example at ./spec/models/update_spec.rb:19 (FAILED - 1)

Failures:

  1) Update 
     Failure/Error: roles {[FactoryGirl.create(:engineer)]}

     ActiveRecord::RecordInvalid:
       Validation failed: Name has already been taken

How can I pass the tests?!

EDIT: By adding the sequence line I was suggested, I get the following error after

Answers


Dheeresha February 2016

Try the following code for the user model

FactoryGirl.define do
  factory :user_engineer, class: User do
    id 1
    email 'someone@somewhere.com'
    roles {[FactoryGirl.create(:engineer, name: "new_engineer")]}
  end
end

Since there is a uniq constraint on the name attribute, I think there is already a engineer record in your test database which got added first time you run test case, So it is better clear the test DB before or after running the test cases.

Put the following block of code in the spec/rails_helper.rb file.

  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end


Arup Rakshit February 2016

As from your error it is clear that you have a uniq validation on name attribute, you should be then use sequence technique.

FactoryGirl.define do
  factory :engineer, class: Role do
    id 3
    sequence(:name) { |n| "Engineer-#{n}" }
    description 'He is the chosen one'
  end
end

Post Status

Asked in February 2016
Viewed 3,951 times
Voted 14
Answered 2 times

Search




Leave an answer