Skip to content

Instantly share code, notes, and snippets.

@jaydorsey
Last active July 30, 2024 14:48
Show Gist options
  • Save jaydorsey/3e7a971ee7497a70fd992990b8aa75ec to your computer and use it in GitHub Desktop.
Save jaydorsey/3e7a971ee7497a70fd992990b8aa75ec to your computer and use it in GitHub Desktop.
FactoryBot factories that share a relationship
# frozen_string_literal: true
# I often find myself wanting to codify relationships/associations in a factory by default, so the
# factory doesn't require myself or other engineers to retain the knowledge about the complex relationships
# and define those relationships in every part of the test
#
# In this contrived example, our models are tenant-aware via a company_id FK on each model:
# - Widget belongs_to a company
# - User belongs to a company
# - A widget has a creator; the creator of the widget and the widget itself must belong to the same company
#
# When I create a widget via a factory, by default I want to add a creator that belongs to the same company
#
# This is a succint alternative to creating these manually every time (or more realistically, requiring
# that everyone needs to know how to create these manually):
#
# let(:company) { create(:company) }
# let(:creator) { create(:user, company:) }
# let(:widget) { create(:widget, creator:, company:) }
#
# Realistically, this example is good for tenancy-based applications where you want to codify in your
# factories, by default, that there is a shared relationship among your references. In this example
# the creator belongs to the same company as the widget.
FactoryBot.define do
factory :widget do
association :company # builds/creates a new company
creator { |widget| widget.association(:user, company: widget.company) } # builds/creates a user, with the same company
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment