class FactoryBot::Factory

@api private

def assert_valid_options(options)

def assert_valid_options(options)
  options.assert_valid_keys(:class, :parent, :aliases, :traits)
end

def associations

def associations
  evaluator_class.attribute_list.associations
end

def attributes

def attributes
  compile
  AttributeList.new(@name).tap do |list|
    list.apply_attributes definition.attributes
  end
end

def build_class

def build_class
  @build_class ||= if class_name.is_a? Class
    class_name
  else
    class_name.to_s.camelize.constantize
  end
end

def build_hierarchy

def build_hierarchy
  hierarchy_class.build_from_definition definition
end

def callbacks

def callbacks
  hierarchy_instance.callbacks
end

def class_name

def class_name
  @class_name || parent.class_name || name
end

def compile

def compile
  unless @compiled
    parent.compile
    parent.defined_traits.each { |trait| define_trait(trait) }
    @definition.compile(build_class)
    build_hierarchy
    @compiled = true
  end
end

def compiled_constructor

def compiled_constructor
  hierarchy_instance.constructor
end

def compiled_to_create

def compiled_to_create
  hierarchy_instance.to_create
end

def evaluator_class

def evaluator_class
  @evaluator_class ||= EvaluatorClassDefiner.new(attributes, parent.evaluator_class).evaluator_class
end

def hierarchy_class

def hierarchy_class
  @hierarchy_class ||= Class.new(parent.hierarchy_class)
end

def hierarchy_instance

def hierarchy_instance
  @hierarchy_instance ||= hierarchy_class.new
end

def human_names

def human_names
  names.map { |name| name.to_s.humanize.downcase }
end

def initialize(name, options = {})

def initialize(name, options = {})
  assert_valid_options(options)
  @name = name.respond_to?(:to_sym) ? name.to_sym : name.to_s.underscore.to_sym
  @parent = options[:parent]
  @aliases = options[:aliases] || []
  @class_name = options[:class]
  @definition = Definition.new(@name, options[:traits] || [])
  @compiled = false
end

def initialize_copy(source)

def initialize_copy(source)
  super
  @definition = @definition.clone
  @evaluator_class = nil
  @hierarchy_class = nil
  @hierarchy_instance = nil
  @compiled = false
end

def names

# => User
FactoryBot.create(:post).author.class

end
author
factory :post do

end
# ...
factory :user, aliases: [:author] do

without factories, such as:
association with the same name, this allows associations to be defined
Because an attribute defined without a value or block will build an

# => User
FactoryBot.create(:author).class

end
# ...
factory :user, aliases: [:author] do

Example:

Names for this factory, including aliases.
def names
  [name] + @aliases
end

def parent

def parent
  if @parent
    FactoryBot::Internal.factory_by_name(@parent)
  else
    NullFactory.new
  end
end

def run(build_strategy, overrides, &block)

def run(build_strategy, overrides, &block)
  block ||= ->(result) { result }
  compile
  strategy = StrategyCalculator.new(build_strategy).strategy.new
  evaluator = evaluator_class.new(strategy, overrides.symbolize_keys)
  attribute_assigner = AttributeAssigner.new(evaluator, build_class, &compiled_constructor)
  evaluation =
    Evaluation.new(evaluator, attribute_assigner, compiled_to_create)
  evaluation.add_observer(CallbacksObserver.new(callbacks, evaluator))
  strategy.result(evaluation).tap(&block)
end

def with_traits(traits)

def with_traits(traits)
  clone.tap do |factory_with_traits|
    factory_with_traits.append_traits traits
  end
end