Class: Formed::Associations::CollectionProxy
- Defined in:
- lib/formed/associations/collection_proxy.rb
Instance Attribute Summary
Attributes inherited from Relation
#klass, #skip_preloading_value
Instance Method Summary collapse
-
#<<(*records) ⇒ Object
(also: #push, #append, #concat)
Adds one or more
records
to 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
attributes
and linked to this object, but have not yet been saved. -
#clear ⇒ Object
Equivalent to
delete_all
. -
#empty? ⇒ Boolean
Returns
true
if the collection is empty. -
#include?(record) ⇒ Boolean
Returns
true
if the givenrecord
is present in the collection. -
#initialize(klass, association) ⇒ CollectionProxy
constructor
:nodoc:.
-
#inspect ⇒ Object
:nodoc:.
- #last(limit = nil) ⇒ Object
- #load_target ⇒ Object
-
#loaded? ⇒ Boolean
(also: #loaded)
Returns
true
if the association has been loaded, otherwisefalse
. -
#prepend(*_args) ⇒ 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::Base.take
. - #target ⇒ Object
- #with_context(context) ⇒ Object
Methods inherited from Relation
#any?, #encode_with, #initialize_copy, #many?, #none?, #one?, #to_ary
Methods included from Relation::Delegation
delegated_classes, uncacheable_methods
Constructor Details
#initialize(klass, association) ⇒ CollectionProxy
:nodoc:
6 7 8 9 10 11 12 |
# File 'lib/formed/associations/collection_proxy.rb', line 6 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>
# ]
429 430 431 |
# File 'lib/formed/associations/collection_proxy.rb', line 429 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
other = [Pet.new(id: 1), Pet.new(id: 2)]
person.pets == other
# => false
360 361 362 |
# File 'lib/formed/associations/collection_proxy.rb', line 360 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
93 94 95 |
# File 'lib/formed/associations/collection_proxy.rb', line 93 def build(attributes = {}, &block) @association.build(attributes, &block) 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.
446 447 448 449 |
# File 'lib/formed/associations/collection_proxy.rb', line 446 def clear delete_all self 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
227 228 229 |
# File 'lib/formed/associations/collection_proxy.rb', line 227 def empty? @association.empty? 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
323 324 325 |
# File 'lib/formed/associations/collection_proxy.rb', line 323 def include?(record) !!@association.include?(record) end |
#inspect ⇒ Object
:nodoc:
493 494 495 496 |
# File 'lib/formed/associations/collection_proxy.rb', line 493 def inspect # :nodoc: load_target if find_from_target? super end |
#last(limit = nil) ⇒ Object
32 33 34 35 36 37 38 |
# File 'lib/formed/associations/collection_proxy.rb', line 32 def last(limit = nil) if limit target.last(limit) else target.last end end |
#load_target ⇒ Object
18 19 20 |
# File 'lib/formed/associations/collection_proxy.rb', line 18 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
27 28 29 |
# File 'lib/formed/associations/collection_proxy.rb', line 27 def loaded? @association.loaded? end |
#prepend(*_args) ⇒ Object
:nodoc:
436 437 438 |
# File 'lib/formed/associations/collection_proxy.rb', line 436 def prepend(*_args) # :nodoc: raise NoMethodError, "prepend on association is not defined. Please use <<, push or append" end |
#proxy_association ⇒ Object
:nodoc:
327 328 329 |
# File 'lib/formed/associations/collection_proxy.rb', line 327 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>
# ]
404 405 406 |
# File 'lib/formed/associations/collection_proxy.rb', line 404 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>]
465 466 467 468 |
# File 'lib/formed/associations/collection_proxy.rb', line 465 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
124 125 126 |
# File 'lib/formed/associations/collection_proxy.rb', line 124 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>]
486 487 |
# File 'lib/formed/associations/collection_proxy.rb', line 486 def reset end |
#reset_scope ⇒ Object
:nodoc:
489 490 491 |
# File 'lib/formed/associations/collection_proxy.rb', line 489 def reset_scope # :nodoc: self end |
#scope ⇒ Object
Returns a Relation
object for the records in this association
332 333 334 |
# File 'lib/formed/associations/collection_proxy.rb', line 332 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.
178 179 180 |
# File 'lib/formed/associations/collection_proxy.rb', line 178 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::Base.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) # => []
65 66 67 |
# File 'lib/formed/associations/collection_proxy.rb', line 65 def take(limit = nil) target.take(limit) end |
#target ⇒ Object
14 15 16 |
# File 'lib/formed/associations/collection_proxy.rb', line 14 def target @association.target end |
#with_context(context) ⇒ Object
98 99 100 |
# File 'lib/formed/associations/collection_proxy.rb', line 98 def with_context(context) each { |record| record.with_context(context) } end |