---
title: Never Fear, Traits are Here
teaser:
tags: web,ruby,open source,testing,factory_bot
author: Josh Clayton
published_on: 2011-08-12
---

I can't count the number of times I've worked on Rails apps where I'm using
Factory Bot and want to declare a factory with multiple parents. We've all been
there, don't lie.

```ruby
    FactoryBot.define do
      factory :user do
        name { "Friendly User" }

        factory :admin do
          admin { true }
        end

        factory :male_user do
          gender { "Male" }
          name   { "John Doe" }

          factory :male_admin_user do
            admin { true }
          end

          factory :teenage_male_user do
            date_of_birth { 15.years.ago }

            factory :teenage_admin_male_user do
              admin { true }
            end
          end
        end

        factory :female_user do
          gender { "Female" }
          name   { "Jane Doe" }

          factory :female_admin_user do
            admin { true }
          end

          factory :teenage_female_user do
            date_of_birth { 15.years.ago }

            factory :teenage_admin_female_user do
              admin { true }
            end
          end
        end
      end
    end
```

Oh, the duplication! This isn't DRY.

[Factory Bot 2.0.4](http://rubygems.org/gems/factory_girl/versions/2.0.4)[^1]
introduces traits. I'll cut to the chase:

```ruby
    FactoryBot.define do
      factory :user do
        name { "Friendly User" }

        trait :admin do
          admin { true }
        end

        trait :male do
          gender { "Male" }
          name   { "John Doe" }
        end

        trait :female do
          gender { "Female" }
          name   { "Jane Doe" }
        end

        trait :teenager do
          date_of_birth { 15.years.ago }
        end

        factory :male_user,                 :traits => [:male]
        factory :female_user,               :traits => [:female]
        factory :teenage_male_user,         :traits => [:teenager, :male]
        factory :teenage_female_user,       :traits => [:teenager, :female]
        factory :male_admin_user,           :traits => [:admin, :male]
        factory :female_admin_user,         :traits => [:admin, :female]
        factory :teenage_admin_male_user,   :traits => [:teenager, :admin, :male]
        factory :teenage_admin_female_user, :traits => [:teenager, :admin, :female]
      end
    end
```

Mix and match however you please. Bonus: you can assign traits like plain-old attributes.

```ruby
    FactoryBot.define do
      factory :user do
        name { "Friendly User" }

        trait :admin do
          admin { true }
        end

        trait :male do
          gender { "Male" }
          name   { "John Doe" }
        end

        factory :male_admin_user do
          male
          admin
        end
      end
    end
```

Many props go out to [Thomas Walpole](https://github.com/twalpole), who helped
get a lot of this written; thanks Thomas!

So go ahead, get your trait on; you'll thank me later.

[^1]: FactoryGirl was renamed to FactoryBot in 2017.
[Project name history can be found here.](https://github.com/thoughtbot/factory_bot/blob/master/NAME.md)
