--- /dev/null
+---
+title: Factory Bot
+category: Ruby libraries
+layout: 2017/sheet
+weight: -3
+updated: 2017-10-31
+keywords:
+ - "FactoryBot.define do"
+ - "factory :user"
+ - "first_name 'John'"
+ - "sequence(:username) { |n| \"user#{n}\" }"
+tags: [Featurable]
+intro: |
+ [Factory Bot](http://www.rubydoc.info/gems/factory_bot/) is a helper for writing factories for Ruby tests.
+ It was previously known as Factory Girl. For older versions, use `FactoryGirl` instead of `FactoryBot`.
+---
+
+## Factories
+{: .-three-column}
+
+### Defining factories
+
+```ruby
+FactoryBot.define do
+ factory :user do
+ first_name 'John'
+ last_name 'Doe'
+ birthdate { 21.years.ago }
+ admin false
+
+ sequence(:username) { |n| "user#{n}" }
+ end
+end
+```
+{: data-line="2"}
+
+See: [Defining factories](http://www.rubydoc.info/gems/factory_bot/file/GETTING_STARTED.md#Defining_factories)
+
+### Extra options
+
+#### Custom class names
+
+```ruby
+factory :user, class: 'User' do
+ ···
+end
+```
+
+#### Aliases
+
+```ruby
+factory :user, aliases: [:author] do
+ ···
+end
+```
+
+### Using
+
+#### Build a model
+
+```ruby
+FactoryBot.build(:user)
+```
+
+#### Other ways
+
+```ruby
+build(:user) # → model (not saved)
+create(:user) # → model (saved)
+attributes_for(:user) # → hash
+build_stubbed(:user) # stubbed out attributes
+```
+
+#### With options
+
+```ruby
+build(:user, name: 'John')
+```
+
+#### Lists
+
+```ruby
+create_list(:user, 3)
+build_list(:user, 3)
+```
+
+## Associations
+
+### Defining
+
+```ruby
+factory :post do
+ association :author, factory: :user
+ association :author, factory: [:user, :admin]
+end
+```
+{: data-line="2,3"}
+
+#### or
+
+```ruby
+factory :post do
+ author # assumes there's a factory :author
+end
+```
+
+### After-create hooks
+
+```ruby
+factory :post do
+ after :create do |post|
+ create :theme, post: post # has_one
+ create_list :comment, 3, post: post # has_many
+ end
+end
+```
+{: data-line="2"}
+
+## Other features
+{: .-three-column}
+
+### Traits
+
+```ruby
+factory :user do
+ trait :admin do
+ admin true
+ end
+end
+```
+{: data-line="2,3,4"}
+
+```ruby
+create :user, :admin
+```
+
+Traits allow you to group attributes together.
+See: [Traits](http://www.rubydoc.info/gems/factory_bot/file/GETTING_STARTED.md#Traits)
+
+### Nested factories
+
+```ruby
+factory :user do
+ first_name 'John'
+
+ factory :sample_user do
+ first_name { FFaker::Name.first_name }
+ end
+end
+```
+{: data-line="4,5,6"}
+
+```ruby
+create :sample_user
+```
+
+See: [Inheritance](http://www.rubydoc.info/gems/factory_bot/file/GETTING_STARTED.md#Inheritance)
+
+### Sub-factories
+
+```ruby
+factory :user do
+ ···
+end
+```
+
+```ruby
+factory :sample_user, parent: :user do
+ first_name { FFaker::Name.first_name }
+end
+```
+{: data-line="1"}
+
+```ruby
+create :sample_user
+```
+
+Works the same as nested factories.
+
+### Options (transients)
+
+```ruby
+factory :user do
+ transient do
+ upcased true
+ end
+
+ after :create do |user, options|
+ user.name.upcase! if options.upcased
+ end
+end
+```
+{: data-line="2,3,4"}
+
+```ruby
+create(user, upcased: true)
+```
+
+Transient attributes will not get passed to the model, but will be available in after-create hooks.
+See: [Transient attributes](http://www.rubydoc.info/gems/factory_bot/file/GETTING_STARTED.md#Transient_Attributes)
+
+### Paths
+
+* test/factories.rb
+* spec/factories.rb
+* test/factories/*.rb
+* spec/factories/*.rb
+
+Place your factories in these locations.
+{: .-setup}
+
+## See also
+{: .-one-column}
+
+* <http://rubydoc.info/gems/factory_bot/file/GETTING_STARTED.md>