class ActiveRecord::Associations::CollectionProxy

instantiation of the actual post records.
is computed directly through SQL and does not trigger by itself the
blog.posts.count
The target result set is not loaded until needed. For example,
relation class via a delegate cache.
This class delegates unknown methods to the association‘s
of posts as the target.
:has_many association, and delegates to a collection
The collection proxy returned by blog.posts is built from a
blog = Blog.first
end
has_many :posts
class Blog < ActiveRecord::Base
For example, given
association, and its target result set.
Collection proxies in Active Record are middlemen between an

def <<(*records)

# ]
# #
# #,
# #,
# => [
person.pets
person.id # => 1

person.pets.size # => 3
person.pets << [Pet.new(name: 'Spook'), Pet.new(name: 'Choo-Choo')]
person.pets << Pet.new(name: 'Fancy-Fancy')
person.pets.size # => 0

end
has_many :pets
class Person < ActiveRecord::Base

so several appends may be chained together.
inserts each record, +push+ and +concat+ behave identically. Returns +self+
to the association's primary key. Since << flattens its argument list and
Adds one or more +records+ to the collection by setting their foreign keys
def <<(*records)
  proxy_association.concat(records) && self
end

def ==(other)

# => false
person.pets == other

other = [Pet.new(id: 1), Pet.new(id: 2)]

# => true
person.pets == other

other = person.pets.to_ary

# ]
# #
# #,
# => [
person.pets

end
has_many :pets
class Person < ActiveRecord::Base

+false+.
to the corresponding element in the +other+ array, otherwise returns
contain the same number of elements and if each element is equal
Equivalent to Array#==. Returns +true+ if the two arrays
def ==(other)
  load_target == other
end

def build(attributes = {}, &block)

person.pets.count # => 0 # count from database
person.pets.size # => 5 # size of the collection

# ]
# #
# #,
# #,
# => [
person.pets.build([{name: 'Spook'}, {name: 'Choo-Choo'}, {name: 'Brain'}])

# => #
person.pets.build(name: 'Fancy-Fancy')

# => #
person.pets.build

end
has_many :pets
class Person

with the new objects.
You can pass an array of attributes hashes, this will return an array
with +attributes+ and linked to this object, but have not yet been saved.
Returns a new object of the collection type that has been instantiated
def build(attributes = {}, &block)
  @association.build(attributes, &block)
end

def calculate(operation, column_name)

--
def calculate(operation, column_name)
  null_scope? ? scope.calculate(operation, column_name) : super
end

def clear

the object is not changed.
running an SQL query into the database, the +updated_at+ column of
Note that because +delete_all+ removes records by directly
+delete_all+ for more information.
of an array with the deleted objects, so methods can be chained. See
Equivalent to +delete_all+. The difference is that returns +self+, instead
def clear
  delete_all
  self
end

def create(attributes = {}, &block)

# ]
# #
# #,
# #,
# => [
person.pets.find(1, 2, 3)

person.pets.count # => 3
person.pets.size # => 3

# ]
# #
# #,
# => [
person.pets.create([{name: 'Spook'}, {name: 'Choo-Choo'}])

# => #
person.pets.create(name: 'Fancy-Fancy')

end
has_many :pets
class Person

passes the validations).
attributes, linked to this object and that has already been saved (if it
Returns a new object of the collection type that has been instantiated with
def create(attributes = {}, &block)
  @association.create(attributes, &block)
end

def create!(attributes = {}, &block)

# => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
person.pets.create!(name: nil)

end
validates :name, presence: true
class Pet

end
has_many :pets
class Person

Like #create, except that if the record is invalid, raises an exception.
def create!(attributes = {}, &block)
  @association.create!(attributes, &block)
end

def delete(*records)

# ]
# #
# #,
# => [
person.pets.delete(2, 3)

# => [#]
person.pets.delete("1")

# ]
# #
# #,
# #,
# => [
person.pets
person.pets.size # => 3

end
has_many :pets
class Person < ActiveRecord::Base

responding to the +id+ and executes delete on them.
You can pass +Integer+ or +String+ values, it finds the records

# => ActiveRecord::RecordNotFound: Couldn't find Pet with 'id'=1
Pet.find(1)

# ]
# #
# #,
# => [
person.pets
person.pets.size # => 2

# => [#]
person.pets.delete(Pet.find(1))

# ]
# #
# #,
# #,
# => [
person.pets
person.pets.size # => 3

end
has_many :pets, dependent: :delete_all
class Person < ActiveRecord::Base

*without* calling their +destroy+ method.
If it is set to :delete_all, all the +records+ are deleted

# => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 3)
Pet.find(1, 3)

# => [#]
person.pets
person.pets.size # => 1

# ]
# #
# #,
# => [
person.pets.delete(Pet.find(1), Pet.find(3))

# ]
# #
# #,
# #,
# => [
person.pets
person.pets.size # => 3

end
has_many :pets, dependent: :destroy
class Person < ActiveRecord::Base

their +destroy+ method. See +destroy+ for more information.
If it is set to :destroy all the +records+ are removed by calling

# => #
Pet.find(1)

# ]
# #
# #,
# => [
person.pets
person.pets.size # => 2

# => [#]
person.pets.delete(Pet.find(1))

# ]
# #
# #,
# #,
# => [
person.pets
person.pets.size # => 3

end
has_many :pets # dependent: :nullify option by default
class Person < ActiveRecord::Base

This sets the foreign keys to +NULL+.
For +has_many+ associations, the default deletion strategy is +:nullify+.

+:delete_all+.
For has_many :through associations, the default deletion strategy is

deleted records.
then it will follow the default strategy. Returns an array with the
specified by the +:dependent+ option. If no +:dependent+ option is given,
Deletes the +records+ supplied from the collection according to the strategy
def delete(*records)
  @association.delete(*records).tap { reset_scope }
end

def delete_all(dependent = nil)

# => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
Pet.find(1, 2, 3)

person.pets.delete_all

# ]
# #
# #,
# #,
# => [
person.pets
person.pets.size # => 3

end
has_many :pets, dependent: :delete_all
class Person < ActiveRecord::Base

*without* calling their +destroy+ method.
If it is set to :delete_all, all the objects are deleted

# => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
Pet.find(1, 2, 3)

person.pets.delete_all

# ]
# #
# #,
# #,
# => [
person.pets
person.pets.size # => 3

end
has_many :pets, dependent: :destroy
class Person < ActiveRecord::Base

Records are not instantiated and callbacks will not be fired.
+:delete_all+ strategy if the +:dependent+ option is set to +:destroy+.
Both +has_many+ and has_many :through dependencies default to the

# ]
# #
# #,
# #,
# => [
Pet.find(1, 2, 3)

person.pets # => []
person.pets.size # => 0

# ]
# #
# #,
# #,
# => [
person.pets.delete_all

# ]
# #
# #,
# #,
# => [
person.pets
person.pets.size # => 3

end
has_many :pets # dependent: :nullify option by default
class Person < ActiveRecord::Base

This sets the foreign keys to +NULL+.
For +has_many+ associations, the default deletion strategy is +:nullify+.

+:delete_all+.
For has_many :through associations, the default deletion strategy is

then it will follow the default strategy.
specified by the +:dependent+ option. If no +:dependent+ option is given,
Deletes all the records from the collection according to the strategy
def delete_all(dependent = nil)
  @association.delete_all(dependent).tap { reset_scope }
end

def destroy(*records)

Pet.find(4, 5, 6) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (4, 5, 6)

person.pets # => []
person.pets.size # => 0

# ]
# #
# #,
# => [
person.pets.destroy(5, 6)

# ]
# #
# #,
# => [
person.pets
person.pets.size # => 2

# => #
person.pets.destroy("4")

# ]
# #
# #,
# #,
# => [
person.pets
person.pets.size # => 3

responding to the +id+ and then deletes them from the database.
You can pass +Integer+ or +String+ values, it finds the records

Pet.find(1, 2, 3) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)

person.pets # => []
person.pets.size # => 0

# ]
# #
# #,
# => [
person.pets.destroy(Pet.find(2), Pet.find(3))

# ]
# #
# #,
# => [
person.pets
person.pets.size # => 2

# => [#]
person.pets.destroy(Pet.find(1))

# ]
# #
# #,
# #,
# => [
person.pets
person.pets.size # => 3

end
has_many :pets
class Person < ActiveRecord::Base

the +:dependent+ option. Returns an array with the removed records.
This method will _always_ remove record from the database ignoring
Destroys the +records+ supplied and removes them from the collection.
def destroy(*records)
  @association.destroy(*records).tap { reset_scope }
end

def destroy_all

Pet.find(1) # => Couldn't find Pet with id=1

person.pets # => []
person.pets.size # => 0

person.pets.destroy_all

# ]
# #
# #,
# #,
# => [
person.pets
person.pets.size # => 3

end
has_many :pets
class Person < ActiveRecord::Base

+after_destroy+ callbacks.
invokes +before_remove+, +after_remove+, +before_destroy+, and
ignoring the +:dependent+ option. Records are instantiated and it
Deletes the records of the collection directly from the database
def destroy_all
  @association.destroy_all.tap { reset_scope }
end

def empty?

person.pets.empty? # => true
person.pets.count # => 0

person.pets.delete_all

person.pets.empty? # => false
person.pets.count # => 1

end
has_many :pets
class Person < ActiveRecord::Base

is better to check collection.load.empty?.
not already been loaded and you are going to fetch the records anyway it
it is equivalent to !collection.exists?. If the collection has
to collection.size.zero?. If the collection has not been loaded,
loaded it is equivalent
Returns +true+ if the collection is empty. If the collection has been
def empty?
  @association.empty?
end

def exec_queries

def exec_queries
  load_target
end

def find(*args)

# ]
# #
# #,
# => [
person.pets.find(2, 3)

# => #
person.pets.find(2) { |pet| pet.name.downcase! }

person.pets.find(4) # => ActiveRecord::RecordNotFound: Couldn't find Pet with 'id'=4
person.pets.find(1) # => #

# ]
# #
# #,
# #,
# => [
person.pets

end
has_many :pets
class Person < ActiveRecord::Base

error if the object cannot be found.
rules as ActiveRecord::Base.find. Returns ActiveRecord::RecordNotFound
Finds an object in the collection responding to the +id+. Uses the same
def find(*args)
  return super if block_given?
  @association.find(*args)
end

def find_from_target?

def find_from_target?
  @association.find_from_target?
end

def find_nth_from_last(index)

def find_nth_from_last(index)
  load_target if find_from_target?
  super
end

def find_nth_with_limit(index, limit)

def find_nth_with_limit(index, limit)
  load_target if find_from_target?
  super
end

def include?(record)

person.pets.include?(Pet.find(21)) # => false
person.pets.include?(Pet.find(20)) # => true

person.pets # => [#]

end
has_many :pets
class Person < ActiveRecord::Base

Returns +true+ if the given +record+ is present in the collection.
def include?(record)
  !!@association.include?(record)
end

def initialize(klass, association, **) # :nodoc:

:nodoc:
def initialize(klass, association, **) # :nodoc:
  @association = association
  super klass
  extensions = association.extensions
  extend(*extensions) if extensions.any?
end

def inspect # :nodoc:

:nodoc:
def inspect # :nodoc:
  load_target if find_from_target?
  super
end

def last(limit = nil)

another_person_without.pets.last(3) # => []
another_person_without.pets.last # => nil
another_person_without.pets # => []

# ]
# #
# #,
# => [
person.pets.last(2)

person.pets.last # => #

# ]
# #
# #,
# #,
# => [
person.pets

end
has_many :pets
class Person < ActiveRecord::Base

form returns an empty array.
If the collection is empty, the first form returns +nil+, and the second
Returns the last record, or the last +n+ records, from the collection.
def last(limit = nil)
  load_target if find_from_target?
  super
end

def load_target

def load_target
  @association.load_target
end

def loaded?

person.pets.loaded? # => true
person.pets.records
person.pets.loaded? # => false

Returns +true+ if the association has been loaded, otherwise +false+.
def loaded?
  @association.loaded?
end

def null_scope?

def null_scope?
  @association.null_scope?
end

def pluck(*column_names)

def pluck(*column_names)
  null_scope? ? scope.pluck(*column_names) : super
end

def prepend(*args) # :nodoc:

:nodoc:
def prepend(*args) # :nodoc:
  raise NoMethodError, "prepend on association is not defined. Please use <<, push or append"
end

def proxy_association # :nodoc:

:nodoc:
def proxy_association # :nodoc:
  @association
end

def records # :nodoc:

:nodoc:
def records # :nodoc:
  load_target
end

def reload

# => [#]
person.pets.reload # fetches pets from the database

# => [#]
person.pets # uses the pets cache

# => [#]
person.pets # fetches pets from the database

end
has_many :pets
class Person < ActiveRecord::Base

Reloads the collection from the database. Returns +self+.
def reload
  proxy_association.reload(true)
  reset_scope
end

def replace(other_array)

# => ActiveRecord::AssociationTypeMismatch: Pet expected, got String
person.pets.replace(["doo", "ggie", "gaga"])

an ActiveRecord::AssociationTypeMismatch error:
If the supplied array has an incorrect association type, it raises

# => [#]
person.pets

person.pets.replace(other_pets)

other_pets = [Pet.new(name: 'Puff', group: 'celebrities')]

# => [#]
person.pets

end
has_many :pets
class Person < ActiveRecord::Base

and delete/add only records that have changed.
Replaces this collection with +other_array+. This will perform a diff
def replace(other_array)
  @association.replace(other_array)
end

def reset

# => [#]
person.pets # fetches pets from the database

person.pets.reset # clears the pets cache

# => [#]
person.pets # uses the pets cache

# => [#]
person.pets # fetches pets from the database

end
has_many :pets
class Person < ActiveRecord::Base

Unloads the association. Returns +self+.
def reset
  proxy_association.reset
  proxy_association.reset_scope
  reset_scope
end

def reset_scope # :nodoc:

:nodoc:
def reset_scope # :nodoc:
  @offsets = @take = nil
  @scope = nil
  self
end

def scope

Returns a Relation object for the records in this association
def scope
  @scope ||= @association.scope
end

def size

# collection.size and no SQL count query is executed.
# Because the collection is already loaded, this will behave like
person.pets.size # => 3

# ]
# #
# #,
# #,
# => [
person.pets # This will execute a SELECT * FROM query

# executes something like SELECT COUNT(*) FROM "pets" WHERE "pets"."person_id" = 1
person.pets.size # => 3

end
has_many :pets
class Person < ActiveRecord::Base

+length+ will take one less query. Otherwise +size+ is more efficient.
equivalent. If not and you are going to need the records anyway
If the collection has been already loaded +size+ and +length+ are

it executes a SELECT COUNT(*) query. Else it calls collection.size.
Returns the size of the collection. If the collection hasn't been loaded,
def size
  @association.size
end

def take(limit = nil)

another_person_without.pets.take(2) # => []
another_person_without.pets.take # => nil
another_person_without.pets # => []

# ]
# #
# #,
# => [
person.pets.take(2)

person.pets.take # => #

# ]
# #
# #,
# #,
# => [
person.pets

end
has_many :pets
class Person < ActiveRecord::Base

using the same rules as ActiveRecord::Base.take.
Gives a record (or N records if a parameter is supplied) from the collection
def take(limit = nil)
  load_target if find_from_target?
  super
end

def target

def target
  @association.target
end