Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: Why Evaluator class is marked as a @api private if its instance is part of to_create API? #1664

Open
jacob-s-son opened this issue Jun 16, 2024 · 0 comments

Comments

@jacob-s-son
Copy link

jacob-s-son commented Jun 16, 2024

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?

@jacob-s-son jacob-s-son changed the title Question: Why Evaluator class is marked as a @api private if it's instance is part of to_create API? Question: Why Evaluator class is marked as a @api private if its instance is part of to_create API? Jun 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant