class ActiveRecord::Associations::HasManyAssociation

:nodoc:
is provided by its child HasManyThroughAssociation.
If the association has a :through option further specialization
This is the proxy that handles a has many association.
= Active Record Has Many Association

def _create_record(attributes, *)

def _create_record(attributes, *)
  if attributes.is_a?(Array)
    super
  else
    update_counter_if_success(super, 1)
  end
end

def concat_records(records, *)

def concat_records(records, *)
  update_counter_if_success(super, records.length)
end

def count_records

the loaded flag is set to true as well.
If the collection is empty the target is set to an empty array and

account and delegates to +count_records+ if needed.
or not. The +size+ method is the one that takes the loaded flag into
That does not depend on whether the collection has already been loaded

to do an SQL count, in those cases the array count will be used.
there's one. Some configuration options like :group make it impossible
it will attempt to do a count via SQL, bounded to :limit if
If the association has a counter cache it gets that value. Otherwise

Returns the number of records in this collection.
def count_records
  count = if reflection.has_cached_counter?
    owner.read_attribute(reflection.counter_cache_column).to_i
  else
    scope.count(:all)
  end
  # If there's nothing in the database, @target should only contain new
  # records or be an empty array. This is a documented side-effect of
  # the method that may avoid an extra SELECT.
  if count == 0
    target.select!(&:new_record?)
    loaded!
  end
  [association_scope.limit_value, count].compact.min
end

def delete_count(method, scope)

def delete_count(method, scope)
  if method == :delete_all
    scope.delete_all
  else
    scope.update_all(nullified_owner_attributes)
  end
end

def delete_or_nullify_all_records(method)

def delete_or_nullify_all_records(method)
  count = delete_count(method, scope)
  update_counter(-count)
  count
end

def delete_records(records, method)

Deletes the records according to the :dependent option.
def delete_records(records, method)
  if method == :destroy
    records.each(&:destroy!)
    update_counter(-records.length) unless reflection.inverse_updates_counter_cache?
  else
    scope = self.scope.where(reflection.klass.primary_key => records)
    update_counter(-delete_count(method, scope))
  end
end

def difference(a, b)

def difference(a, b)
  a - b
end

def handle_dependency

def handle_dependency
  case options[:dependent]
  when :restrict_with_exception
    raise ActiveRecord::DeleteRestrictionError.new(reflection.name) unless empty?
  when :restrict_with_error
    unless empty?
      record = owner.class.human_attribute_name(reflection.name).downcase
      owner.errors.add(:base, :'restrict_dependent_destroy.has_many', record: record)
      throw(:abort)
    end
  when :destroy
    # No point in executing the counter update since we're going to destroy the parent anyway
    load_target.each { |t| t.destroyed_by_association = reflection }
    destroy_all
  when :destroy_async
    load_target.each do |t|
      t.destroyed_by_association = reflection
    end
    unless target.empty?
      association_class = target.first.class
      primary_key_column = association_class.primary_key.to_sym
      ids = target.collect do |assoc|
        assoc.public_send(primary_key_column)
      end
      enqueue_destroy_association(
        owner_model_name: owner.class.to_s,
        owner_id: owner.id,
        association_class: reflection.klass.to_s,
        association_ids: ids,
        association_primary_key_column: primary_key_column,
        ensuring_owner_was_method: options.fetch(:ensuring_owner_was, nil)
      )
    end
  else
    delete_all
  end
end

def insert_record(record, validate = true, raise = false)

def insert_record(record, validate = true, raise = false)
  set_owner_attributes(record)
  super
end

def intersection(a, b)

def intersection(a, b)
  a & b
end

def update_counter(difference, reflection = reflection())

def update_counter(difference, reflection = reflection())
  if reflection.has_cached_counter?
    owner.increment!(reflection.counter_cache_column, difference)
  end
end

def update_counter_if_success(saved_successfully, difference)

def update_counter_if_success(saved_successfully, difference)
  if saved_successfully
    update_counter_in_memory(difference)
  end
  saved_successfully
end

def update_counter_in_memory(difference, reflection = reflection())

def update_counter_in_memory(difference, reflection = reflection())
  if reflection.counter_must_be_updated_by_has_many?
    counter = reflection.counter_cache_column
    owner.increment(counter, difference)
    owner.send(:"clear_#{counter}_change")
  end
end