Today I learned

Using factory_bot with custom factories

Factory Bot is great when creating 'presets' of ActiveRecord models. This is all you really need for most simple cases.

factory :user do
  name { 'John' }
  email { '[email protected]' }
end
create :user
# same as User.create(name: 'John', email: '[email protected]')

Using custom factories

At some point however, your models may get too complicated and you may need an actual factory—a class that constructs an object and performs actions along with it.

class UserCreator
  attr_reader :user

  def initialize(attrs)
    @user = User.create(attrs)
    @user.profile = Profile.create(@user)
    @user.posts = create_sample_post
  end
end
creator = UserCreator.create(name: 'John')
creator.user

Setting it up (the hard way)

Factory Bot will then consume a class in this manner:

user = User.new
user.name = 'John'
user.save!

You can set up a factory_bot factory to use this by passing a class option. You'll have to make your factory implement these methods. This is silly and painful.

factory :real_user, class: 'UserCreator' do
  ...
end
create(:real_user).user

Even easier

Why not use the attributes_for helper instead?

UserCreator.create attributes_for(:user)

Also see

Also see the Factory Bot cheatsheet, along with other cheatsheets from my cheatsheets archive.

You have just read Using factory_bot with custom factories, written on November 28, 2015. This is Today I Learned, a collection of random tidbits I've learned through my day-to-day web development work. I'm Rico Sta. Cruz, @rstacruz on GitHub (and Twitter!).

← More articles