thoughtbot / thoughtbot/factory_bot
Question: Why `Evaluator` class is marked as a `@api private` if its instance is part of `to_create` API?
Nobody has claimed this yet.
- Dominant language
- Ruby
- Stars
- 8.2k
- Forks
- 2.6k
- PR merge metrics
- No merged PRs in 30d
Description
to_create has either arity of one - to_create {|instance| do something } or two to_create {|instance, context| do something with instance and context }
For the context, we are using repository pattern in our app, the entities are immutable structs, so building them is simply initializing a class. Same time persistence is a create(**attrs) method in a repo instance, that returns an entity after saving it to a DB.
This is the snippet I've came up with after some experimenting:
module FactoryBotHelpers
# no clean way (only chain of private methods and vars) to pass our repo class to both initialize_with and to_create
# custom strategies also don't provide access to the class of the factory for some reason
# hence, this helper method
def factory(name, repo_class:, &)
# values that are mandatory to initialize our immutable entities,
# but are set in most cases by ORM when persisting
missing_build_attributes = {
id: -> { GenerateULID.call },
}
FactoryBot.define do
# expectation was that class won't be required as we are overriding initialize_with
# but FactoryBot still tries to figure out class name from factory name
factory name, class: repo_class do
initialize_with do
repo_class.constantize.new.entity_class.new(
**missing_build_attributes.transform_values(&:call),
**attributes,
)
end
to_create do |instance, context|
repo_class.constantize.new.create!(
**instance.attributes.except(
# we need to remove default values that we supplied in initialize_with, but
# we also need to keep the values that were set by the test
missing_build_attributes.keys - context.__override_names__,
),
)
end
instance_eval(&)
end
end
end
module_function :factory
end
But in this case requires access to the names of the overridden attributes via __override_names__. Is it discouraged?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Evaluator class and the to_create callback API referenced in the issue, then check how override_names is exposed. A useful resolution should state whether accessing this private API is supported and, if so, document the supported entry point or explain the intended alternative.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ruby
- Domain
- testing
- Issue type
- Documentation
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100