hellion
hellion

Reputation: 4840

How to use FactoryGirl with a seed.rb file

My seed file is loaded into my test_helper file. When I try to create a role via a factory it fails validation because it already exists (due to the seed file). But, if I use the Role created in the seed to create the associated role in the factory...I get an error because it seems the factory is initiated before the seed file...the factory errors because the Role its looking for hasn't been created yet. Thats confusing.

This factory fails unique role name validation because a role has already been created via the seed file.

FactoryGirl.define do
  factory :account do
    user
    role
  end
end

this factory (calling admin_account as association) errors because the Role hasn't yet been created.

FactoryGirl.define do
  factory :account do
    user

    trait :admin do
      role Role.find_by_name("admin").id # Role "admin" should exist from the seed
    end

    factory :admin_account, traits: [:admin]
  end
end

So, if I don't use the seed file, my factories fail uniqueness validations. If I do use the seed file, the factory fails complaining undefined method `id' for nil:NilClass (NoMethodError).

What am I doing wrong?

Upvotes: 1

Views: 2589

Answers (2)

Karl Wilbur
Karl Wilbur

Reputation: 6207

Add require 'factory_girl_rails' to your db/seeds.rb file.

Here's an example:

db/seeds.rb:

require 'factory_girl_rails'

puts 'Creating Roles.'
%w(guest user admin super-admin super-duper-admin).each do |role|
  FactoryGirl.create(:role, name: role)
end

FactoryGirl.create(:user)

FactoryGirl.create(:admin_user)

spec/factories/roles.rb:

FactoryGirl.define do
  factory :role do
    name { "role_#{rand(9999)}" }

    factory :guest_role, parent: :role do
      name 'guest'
    end

    factory :user_role, parent: :role do
      name 'user'
    end

    factory :admin_role, parent: :role do
      name 'admin'
    end
  end
end

spec/factories/users.rb:

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

    factory :admin_user, parent: :user do
      email '[email protected]'
      after(:create) {|user| user.add_role(:admin)}
    end
  end
end

Upvotes: 4

hellion
hellion

Reputation: 4840

To answer my own question (sort of). DONT USE FACTORY GIRL. Notice the all caps. I know this draws much debate...but, I have to say ditching Factory Girl, ditching RSpec...and going MiniTest with Fixtures made my test environment so much easier to manage and use. I LOVE fixtures! I know this isn't exactly an answer to this question...but, hopefully if anyone finds this post I might inspire them to simplify their app and just use what rails gives you.

Upvotes: 1

Related Questions