Class: ActiveRecord::Associations::CollectionProxy
- Defined in:
- lib/active_record/associations/collection_proxy.rb
Overview
Active Record Collection Proxy
Collection proxies in Active Record are middlemen between an association, and its target result set.
For example, given
class Blog < ActiveRecord::Base
has_many :posts
end
blog = Blog.first
The collection proxy returned by blog.posts is built from a :has_many association, and delegates to a collection of posts as the target.
This class delegates unknown methods to the association‘s relation class via a delegate cache.
The target result set is not loaded until needed. For example,
blog.posts.count
is computed directly through SQL and does not trigger by itself the instantiation of the actual post records.
Constant Summary
Constants inherited from Relation
Relation::CLAUSE_METHODS, Relation::INVALID_METHODS_FOR_DELETE_ALL, Relation::MULTI_VALUE_METHODS, Relation::SINGLE_VALUE_METHODS, Relation::VALUE_METHODS
Constants included from FinderMethods
Constants included from QueryMethods
QueryMethods::FROZEN_EMPTY_ARRAY, QueryMethods::FROZEN_EMPTY_HASH, QueryMethods::VALID_UNSCOPING_VALUES
Constants included from Batches
Batches::DEFAULT_ORDER, Batches::ORDER_IGNORE_MESSAGE
Instance Attribute Summary
Attributes inherited from Relation
#klass, #predicate_builder, #skip_preloading_value, #table
Instance Method Summary collapse
-
#<<(*records) ⇒ Object
(also: #push, #append, #concat)
Adds one or more
recordsto the collection by setting their foreign keys to the association’s primary key. -
#==(other) ⇒ Object
Equivalent to
Array#==. -
#build(attributes = {}, &block) ⇒ Object
(also: #new)
Returns a new object of the collection type that has been instantiated with
attributesand linked to this object, but have not yet been saved. -
#calculate(operation, column_name) ⇒ Object
–.
-
#clear ⇒ Object
Equivalent to
delete_all. -
#create(attributes = {}, &block) ⇒ Object
Returns a new object of the collection type that has been instantiated with attributes, linked to this object and that has already been saved (if it passes the validations).
-
#create!(attributes = {}, &block) ⇒ Object
Like #create, except that if the record is invalid, raises an exception.
-
#delete(*records) ⇒ Object
Deletes the
recordssupplied from the collection according to the strategy specified by the:dependentoption. -
#delete_all(dependent = nil) ⇒ Object
Deletes all the records from the collection according to the strategy specified by the
:dependentoption. -
#destroy(*records) ⇒ Object
Destroys the
recordssupplied and removes them from the collection. -
#destroy_all ⇒ Object
Deletes the records of the collection directly from the database ignoring the
:dependentoption. -
#empty? ⇒ Boolean
Returns
trueif the collection is empty. -
#find(*args) ⇒ Object
Finds an object in the collection responding to the
id. -
#include?(record) ⇒ Boolean
Returns
trueif the givenrecordis present in the collection. -
#initialize(klass, association) ⇒ CollectionProxy
constructor
:nodoc:.
-
#inspect ⇒ Object
:nodoc:.
-
#last(limit = nil) ⇒ Object
Returns the last record, or the last
nrecords, from the collection. - #load_target ⇒ Object
-
#loaded? ⇒ Boolean
(also: #loaded)
Returns
trueif the association has been loaded, otherwisefalse. - #pluck(*column_names) ⇒ Object
-
#prepend(*args) ⇒ Object
:nodoc:.
-
#pretty_print(pp) ⇒ Object
:nodoc:.
-
#proxy_association ⇒ Object
:nodoc:.
-
#records ⇒ Object
:method: to_ary.
-
#reload ⇒ Object
Reloads the collection from the database.
-
#replace(other_array) ⇒ Object
Replaces this collection with
other_array. -
#reset ⇒ Object
Unloads the association.
-
#reset_scope ⇒ Object
:nodoc:.
-
#scope ⇒ Object
Returns a Relation object for the records in this association.
-
#size ⇒ Object
Returns the size of the collection.
-
#take(limit = nil) ⇒ Object
Gives a record (or N records if a parameter is supplied) from the collection using the same rules as ActiveRecord::FinderMethods.take.
- #target ⇒ Object
Methods inherited from Relation
#_exec_scope, #alias_tracker, #any?, #bind_attribute, #blank?, #cache_key, #cache_key_with_version, #cache_version, #create_or_find_by, #create_or_find_by!, #delete_by, #destroy_by, #eager_loading?, #empty_scope?, #encode_with, #explain, #find_or_create_by, #find_or_create_by!, #find_or_initialize_by, #first_or_create, #first_or_create!, #first_or_initialize, #has_limit_or_offset?, #initialize_copy, #joined_includes_values, #load, #load_async, #many?, #none?, #one?, #preload_associations, #scheduled?, #scope_for_create, #scoping, #to_ary, #to_sql, #touch_all, #update, #update!, #update_all, #update_counters, #values, #values_for_queries, #where_values_hash
Methods included from FinderMethods
#exists?, #fifth, #fifth!, #find_by, #find_by!, #find_sole_by, #first, #first!, #forty_two, #forty_two!, #fourth, #fourth!, #last!, #raise_record_not_found_exception!, #second, #second!, #second_to_last, #second_to_last!, #sole, #take!, #third, #third!, #third_to_last, #third_to_last!
Methods included from Calculations
#async_average, #async_count, #async_ids, #async_maximum, #async_minimum, #async_pick, #async_pluck, #async_sum, #average, #count, #ids, #maximum, #minimum, #pick, #sum
Methods included from SpawnMethods
#except, #merge, #merge!, #only, #spawn
Methods included from QueryMethods
#_select!, #and, #and!, #annotate, #annotate!, #arel, #construct_join_dependency, #create_with, #create_with!, #distinct, #distinct!, #eager_load, #eager_load!, #excluding, #excluding!, #extending, #extending!, #extract_associated, #from, #from!, #group, #group!, #having, #having!, #in_order_of, #includes, #includes!, #invert_where, #invert_where!, #joins, #joins!, #left_outer_joins, #left_outer_joins!, #limit, #limit!, #lock, #lock!, #none, #none!, #null_relation?, #offset, #offset!, #optimizer_hints, #optimizer_hints!, #or, #or!, #order, #order!, #preload, #preload!, #readonly, #readonly!, #references, #references!, #regroup, #regroup!, #reorder, #reorder!, #reselect, #reselect!, #reverse_order, #reverse_order!, #rewhere, #select, #skip_preloading!, #skip_query_cache!, #strict_loading, #strict_loading!, #structurally_compatible?, #uniq!, #unscope, #unscope!, #where, #where!, #with, #with!
Methods included from Batches
#find_each, #find_in_batches, #in_batches
Methods included from Explain
#collecting_queries_for_explain, #exec_explain
Methods included from Delegation
delegated_classes, uncacheable_methods
Constructor Details
#initialize(klass, association) ⇒ CollectionProxy
:nodoc:
32 33 34 35 36 37 38 |
# File 'lib/active_record/associations/collection_proxy.rb', line 32 def initialize(klass, association, **) # :nodoc: @association = association super klass extensions = association.extensions extend(*extensions) if extensions.any? end |
Instance Method Details
#<<(*records) ⇒ Object Also known as: push, append, concat
Adds one or more records to the collection by setting their foreign keys to the association’s primary key. Since << flattens its argument list and inserts each record, push and concat behave identically. Returns self so several appends may be chained together.
class Person < ActiveRecord::Base
has_many :pets
end
person.pets.size # => 0
person.pets << Pet.new(name: 'Fancy-Fancy')
person.pets << [Pet.new(name: 'Spook'), Pet.new(name: 'Choo-Choo')]
person.pets.size # => 3
person.id # => 1
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
1036 1037 1038 |
# File 'lib/active_record/associations/collection_proxy.rb', line 1036 def <<(*records) proxy_association.concat(records) && self end |
#==(other) ⇒ Object
Equivalent to Array#==. Returns true if the two arrays contain the same number of elements and if each element is equal to the corresponding element in the other array, otherwise returns false.
class Person < ActiveRecord::Base
has_many :pets
end
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>
# ]
other = person.pets.to_ary
person.pets == other
# => true
Note that unpersisted records can still be seen as equal:
other = [Pet.new(id: 1), Pet.new(id: 2)]
person.pets == other
# => true
967 968 969 |
# File 'lib/active_record/associations/collection_proxy.rb', line 967 def ==(other) load_target == other end |
#build(attributes = {}, &block) ⇒ Object Also known as: new
Returns a new object of the collection type that has been instantiated with attributes and linked to this object, but have not yet been saved. You can pass an array of attributes hashes, this will return an array with the new objects.
class Person
has_many :pets
end
person.pets.build
# => #<Pet id: nil, name: nil, person_id: 1>
person.pets.build(name: 'Fancy-Fancy')
# => #<Pet id: nil, name: "Fancy-Fancy", person_id: 1>
person.pets.build([{name: 'Spook'}, {name: 'Choo-Choo'}, {name: 'Brain'}])
# => [
# #<Pet id: nil, name: "Spook", person_id: 1>,
# #<Pet id: nil, name: "Choo-Choo", person_id: 1>,
# #<Pet id: nil, name: "Brain", person_id: 1>
# ]
person.pets.size # => 5 # size of the collection
person.pets.count # => 0 # count from database
318 319 320 |
# File 'lib/active_record/associations/collection_proxy.rb', line 318 def build(attributes = {}, &block) @association.build(attributes, &block) end |
#calculate(operation, column_name) ⇒ Object
–
724 725 726 |
# File 'lib/active_record/associations/collection_proxy.rb', line 724 def calculate(operation, column_name) null_scope? ? scope.calculate(operation, column_name) : super end |
#clear ⇒ Object
Equivalent to delete_all. The difference is that returns self, instead of an array with the deleted objects, so methods can be chained. See delete_all for more information. Note that because delete_all removes records by directly running an SQL query into the database, the updated_at column of the object is not changed.
1053 1054 1055 1056 |
# File 'lib/active_record/associations/collection_proxy.rb', line 1053 def clear delete_all self end |
#create(attributes = {}, &block) ⇒ Object
Returns a new object of the collection type that has been instantiated with attributes, linked to this object and that has already been saved (if it passes the validations).
class Person
has_many :pets
end
person.pets.create(name: 'Fancy-Fancy')
# => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
person.pets.create([{name: 'Spook'}, {name: 'Choo-Choo'}])
# => [
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.size # => 3
person.pets.count # => 3
person.pets.find(1, 2, 3)
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
349 350 351 |
# File 'lib/active_record/associations/collection_proxy.rb', line 349 def create(attributes = {}, &block) @association.create(attributes, &block) end |
#create!(attributes = {}, &block) ⇒ Object
Like #create, except that if the record is invalid, raises an exception.
class Person
has_many :pets
end
class Pet
validates :name, presence: true
end
person.pets.create!(name: nil)
# => ActiveRecord::RecordInvalid: Validation failed: Name can’t be blank
365 366 367 |
# File 'lib/active_record/associations/collection_proxy.rb', line 365 def create!(attributes = {}, &block) @association.create!(attributes, &block) end |
#delete(*records) ⇒ Object
Deletes the records supplied from the collection according to the strategy specified by the :dependent option. If no :dependent option is given, then it will follow the default strategy. Returns an array with the deleted records.
For has_many :through associations, the default deletion strategy is :delete_all.
For has_many associations, the default deletion strategy is :nullify. This sets the foreign keys to NULL.
class Person < ActiveRecord::Base
has_many :pets # dependent: :nullify option by default
end
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.delete(Pet.find(1))
# => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
person.pets.size # => 2
person.pets
# => [
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
Pet.find(1)
# => #<Pet id: 1, name: "Fancy-Fancy", person_id: nil>
If it is set to :destroy all the records are removed by calling their destroy method. See destroy for more information.
class Person < ActiveRecord::Base
has_many :pets, dependent: :destroy
end
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.delete(Pet.find(1), Pet.find(3))
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.size # => 1
person.pets
# => [#<Pet id: 2, name: "Spook", person_id: 1>]
Pet.find(1, 3)
# => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 3)
If it is set to :delete_all, all the records are deleted without calling their destroy method.
class Person < ActiveRecord::Base
has_many :pets, dependent: :delete_all
end
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.delete(Pet.find(1))
# => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
person.pets.size # => 2
person.pets
# => [
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
Pet.find(1)
# => ActiveRecord::RecordNotFound: Couldn't find Pet with 'id'=1
You can pass Integer or String values, it finds the records responding to the id and executes delete on them.
class Person < ActiveRecord::Base
has_many :pets
end
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.delete("1")
# => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
person.pets.delete(2, 3)
# => [
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
620 621 622 |
# File 'lib/active_record/associations/collection_proxy.rb', line 620 def delete(*records) @association.delete(*records).tap { reset_scope } end |
#delete_all(dependent = nil) ⇒ Object
Deletes all the records from the collection according to the strategy specified by the :dependent option. If no :dependent option is given, then it will follow the default strategy.
For has_many :through associations, the default deletion strategy is :delete_all.
For has_many associations, the default deletion strategy is :nullify. This sets the foreign keys to NULL.
class Person < ActiveRecord::Base
has_many :pets # dependent: :nullify option by default
end
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.delete_all
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.size # => 0
person.pets # => []
Pet.find(1, 2, 3)
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: nil>,
# #<Pet id: 2, name: "Spook", person_id: nil>,
# #<Pet id: 3, name: "Choo-Choo", person_id: nil>
# ]
Both has_many and has_many :through dependencies default to the :delete_all strategy if the :dependent option is set to :destroy. Records are not instantiated and callbacks will not be fired.
class Person < ActiveRecord::Base
has_many :pets, dependent: :destroy
end
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.delete_all
Pet.find(1, 2, 3)
# => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
If it is set to :delete_all, all the objects are deleted without calling their destroy method.
class Person < ActiveRecord::Base
has_many :pets, dependent: :delete_all
end
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.delete_all
Pet.find(1, 2, 3)
# => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
474 475 476 |
# File 'lib/active_record/associations/collection_proxy.rb', line 474 def delete_all(dependent = nil) @association.delete_all(dependent).tap { reset_scope } end |
#destroy(*records) ⇒ Object
Destroys the records supplied and removes them from the collection. This method will always remove record from the database ignoring the :dependent option. Returns an array with the removed records.
class Person < ActiveRecord::Base
has_many :pets
end
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.destroy(Pet.find(1))
# => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
person.pets.size # => 2
person.pets
# => [
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.destroy(Pet.find(2), Pet.find(3))
# => [
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.size # => 0
person.pets # => []
Pet.find(1, 2, 3) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
You can pass Integer or String values, it finds the records responding to the id and then deletes them from the database.
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 4, name: "Benny", person_id: 1>,
# #<Pet id: 5, name: "Brain", person_id: 1>,
# #<Pet id: 6, name: "Boss", person_id: 1>
# ]
person.pets.destroy("4")
# => #<Pet id: 4, name: "Benny", person_id: 1>
person.pets.size # => 2
person.pets
# => [
# #<Pet id: 5, name: "Brain", person_id: 1>,
# #<Pet id: 6, name: "Boss", person_id: 1>
# ]
person.pets.destroy(5, 6)
# => [
# #<Pet id: 5, name: "Brain", person_id: 1>,
# #<Pet id: 6, name: "Boss", person_id: 1>
# ]
person.pets.size # => 0
person.pets # => []
Pet.find(4, 5, 6) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (4, 5, 6)
692 693 694 |
# File 'lib/active_record/associations/collection_proxy.rb', line 692 def destroy(*records) @association.destroy(*records).tap { reset_scope } end |
#destroy_all ⇒ Object
Deletes the records of the collection directly from the database ignoring the :dependent option. Records are instantiated and it invokes before_remove, after_remove, before_destroy, and after_destroy callbacks.
class Person < ActiveRecord::Base
has_many :pets
end
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.destroy_all
person.pets.size # => 0
person.pets # => []
Pet.find(1) # => Couldn't find Pet with id=1
501 502 503 |
# File 'lib/active_record/associations/collection_proxy.rb', line 501 def destroy_all @association.destroy_all.tap { reset_scope } end |
#empty? ⇒ Boolean
Returns true if the collection is empty. If the collection has been loaded it is equivalent to collection.size.zero?. If the collection has not been loaded, it is equivalent to !collection.exists?. If the collection has not already been loaded and you are going to fetch the records anyway it is better to check collection.load.empty?.
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
831 832 833 |
# File 'lib/active_record/associations/collection_proxy.rb', line 831 def empty? @association.empty? end |
#find(*args) ⇒ Object
Finds an object in the collection responding to the id. Uses the same rules as ActiveRecord::FinderMethods.find. Returns ActiveRecord::RecordNotFound error if the object cannot be found.
class Person < ActiveRecord::Base
has_many :pets
end
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.find(1) # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
person.pets.find(4) # => ActiveRecord::RecordNotFound: Couldn't find Pet with 'id'=4
person.pets.find(2) { |pet| pet.name.downcase! }
# => #<Pet id: 2, name: "fancy-fancy", person_id: 1>
person.pets.find(2, 3)
# => [
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
138 139 140 141 |
# File 'lib/active_record/associations/collection_proxy.rb', line 138 def find(*args) return super if block_given? @association.find(*args) end |
#include?(record) ⇒ Boolean
Returns true if the given record is present in the collection.
class Person < ActiveRecord::Base
has_many :pets
end
person.pets # => [#<Pet id: 20, name: "Snoop">]
person.pets.include?(Pet.find(20)) # => true
person.pets.include?(Pet.find(21)) # => false
927 928 929 |
# File 'lib/active_record/associations/collection_proxy.rb', line 927 def include?(record) !!@association.include?(record) end |
#inspect ⇒ Object
:nodoc:
1105 1106 1107 1108 |
# File 'lib/active_record/associations/collection_proxy.rb', line 1105 def inspect # :nodoc: load_target if find_from_target? super end |
#last(limit = nil) ⇒ Object
Returns the last record, or the last n records, from the collection. If the collection is empty, the first form returns nil, and the second form returns an empty array.
class Person < ActiveRecord::Base
has_many :pets
end
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.last # => #<Pet id: 3, name: "Choo-Choo", person_id: 1>
person.pets.last(2)
# => [
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
another_person_without.pets # => []
another_person_without.pets.last # => nil
another_person_without.pets.last(3) # => []
259 260 261 262 |
# File 'lib/active_record/associations/collection_proxy.rb', line 259 def last(limit = nil) load_target if find_from_target? super end |
#load_target ⇒ Object
44 45 46 |
# File 'lib/active_record/associations/collection_proxy.rb', line 44 def load_target @association.load_target end |
#loaded? ⇒ Boolean Also known as: loaded
Returns true if the association has been loaded, otherwise false.
person.pets.loaded? # => false
person.pets.records
person.pets.loaded? # => true
53 54 55 |
# File 'lib/active_record/associations/collection_proxy.rb', line 53 def loaded? @association.loaded? end |
#pluck(*column_names) ⇒ Object
728 729 730 |
# File 'lib/active_record/associations/collection_proxy.rb', line 728 def pluck(*column_names) null_scope? ? scope.pluck(*column_names) : super end |
#prepend(*args) ⇒ Object
:nodoc:
1043 1044 1045 |
# File 'lib/active_record/associations/collection_proxy.rb', line 1043 def prepend(*args) # :nodoc: raise NoMethodError, "prepend on association is not defined. Please use <<, push or append" end |
#pretty_print(pp) ⇒ Object
:nodoc:
1110 1111 1112 1113 |
# File 'lib/active_record/associations/collection_proxy.rb', line 1110 def pretty_print(pp) # :nodoc: load_target if find_from_target? super end |
#proxy_association ⇒ Object
:nodoc:
931 932 933 |
# File 'lib/active_record/associations/collection_proxy.rb', line 931 def proxy_association # :nodoc: @association end |
#records ⇒ Object
:method: to_ary
:call-seq:
to_ary()
Returns a new array of objects from the collection. If the collection hasn’t been loaded, it fetches the records from the database.
class Person < ActiveRecord::Base
has_many :pets
end
person.pets
# => [
# #<Pet id: 4, name: "Benny", person_id: 1>,
# #<Pet id: 5, name: "Brain", person_id: 1>,
# #<Pet id: 6, name: "Boss", person_id: 1>
# ]
other_pets = person.pets.to_ary
# => [
# #<Pet id: 4, name: "Benny", person_id: 1>,
# #<Pet id: 5, name: "Brain", person_id: 1>,
# #<Pet id: 6, name: "Boss", person_id: 1>
# ]
other_pets.replace([Pet.new(name: 'BooGoo')])
other_pets
# => [#<Pet id: nil, name: "BooGoo", person_id: 1>]
person.pets
# This is not affected by replace
# => [
# #<Pet id: 4, name: "Benny", person_id: 1>,
# #<Pet id: 5, name: "Brain", person_id: 1>,
# #<Pet id: 6, name: "Boss", person_id: 1>
# ]
1011 1012 1013 |
# File 'lib/active_record/associations/collection_proxy.rb', line 1011 def records # :nodoc: load_target end |
#reload ⇒ Object
Reloads the collection from the database. Returns self.
class Person < ActiveRecord::Base
has_many :pets
end
person.pets # fetches pets from the database
# => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
person.pets # uses the pets cache
# => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
person.pets.reload # fetches pets from the database
# => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
1072 1073 1074 1075 |
# File 'lib/active_record/associations/collection_proxy.rb', line 1072 def reload proxy_association.reload(true) reset_scope end |
#replace(other_array) ⇒ Object
Replaces 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
# => [#<Pet id: 1, name: "Gorby", group: "cats", person_id: 1>]
other_pets = [Pet.new(name: 'Puff', group: 'celebrities')]
person.pets.replace(other_pets)
person.pets
# => [#<Pet id: 2, name: "Puff", group: "celebrities", person_id: 1>]
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
391 392 393 |
# File 'lib/active_record/associations/collection_proxy.rb', line 391 def replace(other_array) @association.replace(other_array) end |
#reset ⇒ Object
Unloads the association. Returns self.
class Person < ActiveRecord::Base
has_many :pets
end
person.pets # fetches pets from the database
# => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
person.pets # uses the pets cache
# => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
person.pets.reset # clears the pets cache
person.pets # fetches pets from the database
# => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
1093 1094 1095 1096 1097 |
# File 'lib/active_record/associations/collection_proxy.rb', line 1093 def reset proxy_association.reset proxy_association.reset_scope reset_scope end |
#reset_scope ⇒ Object
:nodoc:
1099 1100 1101 1102 1103 |
# File 'lib/active_record/associations/collection_proxy.rb', line 1099 def reset_scope # :nodoc: @offsets = @take = nil @scope = nil self end |
#scope ⇒ Object
Returns a Relation object for the records in this association
936 937 938 |
# File 'lib/active_record/associations/collection_proxy.rb', line 936 def scope @scope ||= @association.scope end |
#size ⇒ Object
Returns the size of the collection. If the collection hasn’t been loaded, it executes a SELECT COUNT(*) query. Else it calls collection.size.
If the collection has been already loaded size and length are equivalent. If not and you are going to need the records anyway length will take one less query. Otherwise size is more efficient.
class Person < ActiveRecord::Base
has_many :pets
end
person.pets.size # => 3
# executes something like SELECT COUNT(*) FROM "pets" WHERE "pets"."person_id" = 1
person.pets # This will execute a SELECT * FROM query
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.size # => 3
# Because the collection is already loaded, this will behave like
# collection.size and no SQL count query is executed.
782 783 784 |
# File 'lib/active_record/associations/collection_proxy.rb', line 782 def size @association.size end |
#take(limit = nil) ⇒ Object
Gives a record (or N records if a parameter is supplied) from the collection using the same rules as ActiveRecord::FinderMethods.take.
class Person < ActiveRecord::Base
has_many :pets
end
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.take # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
person.pets.take(2)
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>
# ]
another_person_without.pets # => []
another_person_without.pets.take # => nil
another_person_without.pets.take(2) # => []
289 290 291 292 |
# File 'lib/active_record/associations/collection_proxy.rb', line 289 def take(limit = nil) load_target if find_from_target? super end |
#target ⇒ Object
40 41 42 |
# File 'lib/active_record/associations/collection_proxy.rb', line 40 def target @association.target end |