From 1b5c775e7a6d5457da6d2fe02e9e72c6788a7373 Mon Sep 17 00:00:00 2001 From: Francesco Rodriguez Date: Fri, 18 May 2012 15:27:29 -0500 Subject: [PATCH] move docs from CollectionAssociation to CollectionProxy --- .../associations/collection_association.rb | 114 +------------- .../associations/collection_proxy.rb | 143 +++++++++++++++++- 2 files changed, 143 insertions(+), 114 deletions(-) diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb index 9abe648708bbb..aa354d9009d4c 100644 --- a/activerecord/lib/active_record/associations/collection_association.rb +++ b/activerecord/lib/active_record/associations/collection_association.rb @@ -24,7 +24,7 @@ module Associations # # If you need to work on all current children, new and existing records, # +load_target+ and the +loaded+ flag are your friends. - class CollectionAssociation < Association + class CollectionAssociation < Association #:nodoc: # Implements the reader method, e.g. foo.items for Foo.has_many :items def reader(force_reload = false) @@ -127,16 +127,6 @@ def create!(attributes = {}, options = {}, &block) # Add +records+ to this association. Returns +self+ so method calls may # be chained. Since << flattens its argument list and inserts each record, # +push+ and +concat+ behave identically. - # - # class Person < ActiveRecord::Base - # pets :has_many - # end - # - # person.pets << Person.new(name: 'Nemo') - # person.pets.concat(Person.new(name: 'Droopy')) - # person.pets.push(Person.new(name: 'Ren')) - # - # person.pets # => [#, #, #] def concat(*records) load_target if owner.new_record? @@ -181,17 +171,6 @@ def delete_all_on_destroy # Destroy all the records from this association. # - # class Person < ActiveRecord::Base - # has_many :pets - # end - # - # person.pets.size # => 3 - # - # person.pets.destroy_all - # - # person.pets.size # => 0 - # person.pets # => [] - # # See destroy for more info. def destroy_all destroy(load_target).tap do @@ -302,51 +281,12 @@ def length # collection.size.zero?. If the collection has not been already # loaded and you are going to fetch the records anyway it is better to # check collection.length.zero?. - # - # class Person < ActiveRecord::Base - # has_many :pets - # end - # - # person.pets.count # => 1 - # person.pets.empty? # => false - # - # person.pets.delete_all - # person.pets.count # => 0 - # person.pets.empty? # => true def empty? size.zero? end # Returns true if the collections is not empty. # Equivalent to +!collection.empty?+. - # - # class Person < ActiveRecord::Base - # has_many :pets - # end - # - # person.pets.count # => 0 - # person.pets.any? # => false - # - # person.pets << Pet.new(name: 'Snoop') - # person.pets.count # => 0 - # person.pets.any? # => true - # - # Also, you can pass a block to define a criteria. The behaviour - # is the same, it returns true if the collection based on the - # criteria is not empty. - # - # person.pets - # # => [#] - # - # person.pets.any? do |pet| - # pet.group == 'cats' - # end - # # => false - # - # person.pets.any? do |pet| - # pet.group == 'dogs' - # end - # # => true def any? if block_given? load_target.any? { |*block_args| yield(*block_args) } @@ -357,38 +297,6 @@ def any? # Returns true if the collection has more than 1 record. # Equivalent to +collection.size > 1+. - # - # class Person < ActiveRecord::Base - # has_many :pets - # end - # - # person.pets.count #=> 1 - # person.pets.many? #=> false - # - # person.pets << Pet.new(name: 'Snoopy') - # person.pets.count #=> 2 - # person.pets.many? #=> true - # - # Also, you can pass a block to define a criteria. The - # behaviour is the same, it returns true if the collection - # based on the criteria has more than 1 record. - # - # person.pets - # # => [ - # # #, - # # #, - # # # - # # ] - # - # person.pets.many? do |pet| - # pet.group == 'dogs' - # end - # # => false - # - # person.pets.many? do |pet| - # pet.group == 'cats' - # end - # # => true def many? if block_given? load_target.many? { |*block_args| yield(*block_args) } @@ -406,26 +314,6 @@ def uniq(collection = load_target) # Replace this collection with +other_array+. This will perform a diff # and delete/add only records that have changed. - # - # class Person < ActiveRecord::Base - # has_many :pets - # end - # - # person.pets - # # => [#] - # - # other_pets = [Pet.new(name: 'GorbyPuff', group: 'celebrities'] - # - # person.pets.replace(other_pets) - # - # person.pets - # # => [#] - # - # If the supplied array has an incorrect association type, it raises - # an ActiveRecord::AssociationTypeMismatch error: - # - # person.pets.replace(["doo", "ggie", "gaga"]) - # # => ActiveRecord::AssociationTypeMismatch: Pet expected, got String def replace(other_array) other_array.each { |val| raise_on_type_mismatch(val) } original_target = load_target.dup diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb index cf4cc98f38bcd..40f59f2c77ed7 100644 --- a/activerecord/lib/active_record/associations/collection_proxy.rb +++ b/activerecord/lib/active_record/associations/collection_proxy.rb @@ -33,9 +33,150 @@ module Associations # # is computed directly through SQL and does not trigger by itself the # instantiation of the actual post records. - class CollectionProxy < Relation # :nodoc: + class CollectionProxy < Relation delegate :target, :load_target, :loaded?, :to => :@association + ## + # :method: concat + # Add +records+ to this association. Returns +self+ so method calls may + # be chained. Since << flattens its argument list and inserts each record, + # +push+ and +concat+ behave identically. + # + # class Person < ActiveRecord::Base + # pets :has_many + # end + # + # person.pets << Person.new(name: 'Nemo') + # person.pets.concat(Person.new(name: 'Droopy')) + # person.pets.push(Person.new(name: 'Ren')) + # + # person.pets # => [#, #, #] + + ## + # :method: replace + # Replace this collection with +other_array+. This will perform a diff + # and delete/add only records that have changed. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets + # # => [#] + # + # other_pets = [Pet.new(name: 'GorbyPuff', group: 'celebrities'] + # + # person.pets.replace(other_pets) + # + # person.pets + # # => [#] + # + # If the supplied array has an incorrect association type, it raises + # an ActiveRecord::AssociationTypeMismatch error: + # + # person.pets.replace(["doo", "ggie", "gaga"]) + # # => ActiveRecord::AssociationTypeMismatch: Pet expected, got String + + ## + # :method: destroy_all + # Destroy all the records from this association. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets.size # => 3 + # + # person.pets.destroy_all + # + # person.pets.size # => 0 + # person.pets # => [] + + ## + # :method: empty? + # Returns true if the collection is empty. + # Equivalent to +size.zero?+. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets.count # => 1 + # person.pets.empty? # => false + # + # person.pets.delete_all + # person.pets.count # => 0 + # person.pets.empty? # => true + + ## + # :method: any? + # Returns true if the collections is not empty. + # Equivalent to +!collection.empty?+. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets.count # => 0 + # person.pets.any? # => false + # + # person.pets << Pet.new(name: 'Snoop') + # person.pets.count # => 0 + # person.pets.any? # => true + # + # Also, you can pass a block to define a criteria. The behaviour + # is the same, it returns true if the collection based on the + # criteria is not empty. + # + # person.pets + # # => [#] + # + # person.pets.any? do |pet| + # pet.group == 'cats' + # end + # # => false + # + # person.pets.any? do |pet| + # pet.group == 'dogs' + # end + # # => true + + ## + # :method: many? + # Returns true if the collection has more than 1 record. + # Equivalent to +collection.size > 1+. + # + # class Person < ActiveRecord::Base + # has_many :pets + # end + # + # person.pets.count #=> 1 + # person.pets.many? #=> false + # + # person.pets << Pet.new(name: 'Snoopy') + # person.pets.count #=> 2 + # person.pets.many? #=> true + # + # Also, you can pass a block to define a criteria. The + # behaviour is the same, it returns true if the collection + # based on the criteria has more than 1 record. + # + # person.pets + # # => [ + # # #, + # # #, + # # # + # # ] + # + # person.pets.many? do |pet| + # pet.group == 'dogs' + # end + # # => false + # + # person.pets.many? do |pet| + # pet.group == 'cats' + # end + # # => true delegate :select, :find, :first, :last, :build, :create, :create!, :concat, :replace, :delete_all, :destroy_all, :delete, :destroy, :uniq,