class ActiveRecord::Associations::HasManyAssociation
Experimental RBS support (using type sampling data from the type_fusion
project).
# sig/active_record/associations/has_many_association.rbs class ActiveRecord::Associations::HasManyAssociation < ActiveRecord::Associations::CollectionAssociation def insert_record: (AccountUser record, ?true validate, ?false raise) -> true end
: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
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)
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)
Experimental RBS support (using type sampling data from the type_fusion
project).
def insert_record: (AccountUser record, ?true validate, ?false raise) -> true
This signature was generated using 1 sample from 1 application.
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