factory_bot icon indicating copy to clipboard operation
factory_bot copied to clipboard

has_many relations

Open mike-burns opened this issue 1 year ago • 1 comments

I'd like to be able to clearly, safely, and idiomatically create an object and its many relations. For example:

new_author = create(:author)
distinguished_author = create(:author, with_article_count: 3)

assert_equal new_author.articles.count, 0
assert_equal distinguished_author.articles.count, 3

The above can currently be done using a transient property and some hooks, but it's kinda kludgy and hard to get right. Let's make this somewhat common case easier and less error prone.

It could look like this:

FactoryBot.define do
  factory :author do
    association(:article, relation: :has_many)
  end
end

Or it could allow overrides:

FactoryBot.define do
  factory :author do
    association(:unique_article, relation: :has_many) do |user, offset|
      title { "How to win, part #{offset + 1}" } # sets the title for the article
    end
  end
end

mike-burns avatar May 10 '24 16:05 mike-burns

This would be pretty great. If pursued, I would suggest the api look more like the current *[strategy]_list pattern rather than passing in a relation argument. That is:

  association_list(:article, 1)

I typically use a transient association count to avoid duplication & allow count overrides. Something like:

factory :author do
  transient do
    article_count { 0 }
  end

  articles do
    Array.new(article_count) { association :article, author: instance }
  end

  trait :with_article do # typically use this trait, but could pass in article_count
    article_count { 1 }
  end
end

such cases could look like this:

factory :author do
  transient do
    article_count { 0 }
  end

  articles do
    association_list :article, article_count, author: instance
  end

  trait :with_article do
    article_count { 1 }
  end
end

(I think the last bit about an override block seems like a separate concern... better handled by the association factory it is calling.)

thejonroberts avatar Oct 28 '24 18:10 thejonroberts