Skip to content

Commit

Permalink
Make the evaluator instance public
Browse files Browse the repository at this point in the history
closes thoughtbot#1309

It has come up several times over the years that folks want direct
access to the evaluator instance, in most cases to build up more complex
networks of associations. Some folks are already doing this with the
less public `@instance` instance variable.

Given that this is such a minimal change, and it makes the library more
flexible for these more complex use cases, this commit adds an
`attr_reader` for the evaluator instance. Now folks can reference it
without reaching into the private api.

Documentation to follow as part of
thoughtbot#1268
  • Loading branch information
composerinteralia committed Jul 8, 2020
1 parent 5c071d4 commit ebc4cd5
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/factory_bot/evaluator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def association(factory_name, *traits_and_overrides)
@build_strategy.association(runner)
end

attr_writer :instance
attr_accessor :instance

if ::Gem::Version.new(::RUBY_VERSION) >= ::Gem::Version.new("2.7")
def method_missing(method_name, *args, **kwargs, &block) # rubocop:disable Style/MethodMissingSuper, Style/MissingRespondToMissing
Expand Down
69 changes: 69 additions & 0 deletions spec/acceptance/associations_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,73 @@
)
end
end

context "when building interrelated associations" do
it "assigns the instance passed as an association attribute" do
define_class("Supplier") do
attr_accessor :account
end

define_class("Account") do
attr_accessor :supplier
end

FactoryBot.define do
factory :supplier

factory :account do
supplier { association(:supplier, account: instance) }
end
end

account = FactoryBot.build(:account)

expect(account.supplier.account).to eq(account)
end

it "connects records with interdependent relationships" do
define_model("User", school_id: :integer) do
belongs_to :school
has_one :profile
end

define_model("Profile", school_id: :integer, user_id: :integer) do
belongs_to :school
belongs_to :user
end

define_model("School") do
has_many :users
has_many :profiles
end

FactoryBot.define do
factory :user do
school
profile { association :profile, user: instance, school: school }
end

factory :profile do
school
user { association :user, profile: instance, school: school }
end

factory :school
end

user = FactoryBot.create(:user)

expect(user.profile.school).to eq(user.school)
expect(user.profile.user).to eq(user)
expect(user.school.users.map(&:id)).to eq([user.id])
expect(user.school.profiles.map(&:id)).to eq([user.profile.id])

profile = FactoryBot.create(:profile)

expect(profile.user.school).to eq(profile.school)
expect(profile.user.profile).to eq(profile)
expect(profile.school.profiles.map(&:id)).to eq([profile.id])
expect(profile.school.users.map(&:id)).to eq([profile.user.id])
end
end
end

0 comments on commit ebc4cd5

Please sign in to comment.