class ActiveRecord::Associations::Builder::Association

:nodoc:
:nodoc:

def self.add_after_commit_jobs_callback(model, dependent)

def self.add_after_commit_jobs_callback(model, dependent)
  if dependent == :destroy_async
    mixin = model.generated_association_methods
    unless mixin.method_defined?(:_after_commit_jobs)
      model.after_commit(-> do
        _after_commit_jobs.each do |job_class, job_arguments|
          job_class.perform_later(**job_arguments)
        end
      end)
      mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
        def _after_commit_jobs
          @_after_commit_jobs ||= []
        end
      CODE
    end
  end
end

def self.add_destroy_callbacks(model, reflection)

def self.add_destroy_callbacks(model, reflection)
  name = reflection.name
  model.before_destroy(->(o) { o.association(name).handle_dependency })
end

def self.build(model, name, scope, options, &block)

def self.build(model, name, scope, options, &block)
  if model.dangerous_attribute_method?(name)
    raise ArgumentError, "You tried to define an association named #{name} on the model #{model.name}, but " \
                         "this will conflict with a method #{name} already defined by Active Record. " \
                         "Please choose a different association name."
  end
  reflection = create_reflection(model, name, scope, options, &block)
  define_accessors model, reflection
  define_callbacks model, reflection
  define_validations model, reflection
  define_change_tracking_methods model, reflection
  reflection
end

def self.build_scope(scope)

def self.build_scope(scope)
  if scope && scope.arity == 0
    proc { instance_exec(&scope) }
  else
    scope
  end
end

def self.check_dependent_options(dependent, model)

def self.check_dependent_options(dependent, model)
  if dependent == :destroy_async && !model.destroy_association_async_job
    err_message = "ActiveJob is required to use destroy_async on associations"
    raise ActiveRecord::ActiveJobRequiredError, err_message
  end
  unless valid_dependent_options.include? dependent
    raise ArgumentError, "The :dependent option must be one of #{valid_dependent_options}, but is :#{dependent}"
  end
end

def self.create_reflection(model, name, scope, options, &block)

def self.create_reflection(model, name, scope, options, &block)
  raise ArgumentError, "association names must be a Symbol" unless name.kind_of?(Symbol)
  validate_options(options)
  extension = define_extensions(model, name, &block)
  options[:extend] = [*options[:extend], extension] if extension
  scope = build_scope(scope)
  ActiveRecord::Reflection.create(macro, name, scope, options, model)
end

def self.define_accessors(model, reflection)

Post.first.comments and Post.first.comments= methods are defined by this method...

end
has_many :comments
class Post < ActiveRecord::Base
Defines the setter and getter methods for the association
def self.define_accessors(model, reflection)
  mixin = model.generated_association_methods
  name = reflection.name
  define_readers(mixin, name)
  define_writers(mixin, name)
end

def self.define_callbacks(model, reflection)

def self.define_callbacks(model, reflection)
  if dependent = reflection.options[:dependent]
    check_dependent_options(dependent, model)
    add_destroy_callbacks(model, reflection)
    add_after_commit_jobs_callback(model, dependent)
  end
  Association.extensions.each do |extension|
    extension.build model, reflection
  end
end

def self.define_change_tracking_methods(model, reflection)

def self.define_change_tracking_methods(model, reflection)
  # noop
end

def self.define_extensions(model, name)

def self.define_extensions(model, name)
end

def self.define_readers(mixin, name)

def self.define_readers(mixin, name)
  mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
    def #{name}
      association(:#{name}).reader
    end
  CODE
end

def self.define_validations(model, reflection)

def self.define_validations(model, reflection)
  # noop
end

def self.define_writers(mixin, name)

def self.define_writers(mixin, name)
  mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
    def #{name}=(value)
      association(:#{name}).writer(value)
    end
  CODE
end

def self.macro

def self.macro
  raise NotImplementedError
end

def self.valid_dependent_options

def self.valid_dependent_options
  raise NotImplementedError
end

def self.valid_options(options)

def self.valid_options(options)
  VALID_OPTIONS + Association.extensions.flat_map(&:valid_options)
end

def self.validate_options(options)

def self.validate_options(options)
  options.assert_valid_keys(valid_options(options))
end