Hi. I am travis and I work in a place long ago abandoned by the gods: New York City. By day, I am a Software Engineer at Blue Apron. By night, i am a normal person.

FactoryGirl First Or Create

Let's just say FactoryGirl doesn't have a feature like this for a reason. If you're running into a situation where, for example, tests are failing because your database is throwing uniqueness constraint errors, you've probably done something wrong. You should stop reading this and go fix it properly.

If you're still here, then I've got a janky and brittle (read: epic) solution for you! To illustrate:

module FactoryGirlHelper
  BLACKLIST = [:user]

  def first(args)
    name = args.first
    klass = name.to_s.camelize.constantize

    conditions = args.last

    if conditions.present? && conditions.is_a?(Hash)

  def first_or_create(*args)
    result = first(args) if BLACKLIST.include?(args.first)
    result || FactoryGirl.create(*args)

This helper implements a first_or_create call and attempts to find an object matching the parameters passed in. It only calls FactoryGirl's create if the where returns an empty relation, or if the model being created is not in the BLACKLIST. Disclaimer: this is not going to work with traits. Don't forget to include the helper in your RSpec config:

# In rails_helper.rb
RSpec.configure do |config|
  config.include FactoryGirlHelper

Let's write a test for this functionality and make sure it works:

require 'rails_helper'

RSpec.describe FactoryGirlHelper do
  subject do
    first_or_create(:user, first_name: 'Donald', last_name: 'Trump')
    first_or_create(:user, first_name: 'Donald', last_name: 'Trump')

  it 'I am the only one who can make this app great again' do
    expect(FactoryGirl).to receive(:create).once.and_call_original

# Output
1/1 |========================= 100 ==========================>| Time: 00:00:03

Top 1 slowest examples (1.29 seconds, 53.3% of total time):
  FactoryGirlHelper I am the only one who can make this app great again
    1.29 seconds ./spec/helpers/factory_girl_helper_spec.rb:9

Finished in 2.41 seconds (files took 0.76389 seconds to load)
1 example, 0 failures

Of course it works! Now, your flaky test suite has an extra band-aid that will keep it running for at least another few days. It's very important to remember that this is a Trump solution, so now your app will only get worse and you'll have even more tech debt to default on, but you will also have the world's greatest app. It's a fantastic app, by the way. Everyone agrees that your app is fantastic.

Intro to Avro

RSpec Search & Destroy