Class: ActiveEntity::Associations::Embeds::CollectionProxy

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/active_entity/associations/embeds/collection_proxy.rb

Overview

Association proxies in Active Entity are middlemen between the object that holds the association, known as the @owner, and the actual associated object, known as the @target. The kind of association any proxy is about is available in @reflection. That’s an instance of the class ActiveEntity::Reflection::AssociationReflection.

For example, given

class Blog < ActiveEntity::Base
  has_many :posts
end

blog = Blog.first

the association proxy in blog.posts has the object in blog as @owner, the collection of its posts as @target, and the @reflection object represents a :has_many macro.

This class delegates unknown methods to @target via method_missing.

The @target object 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.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass, association) ⇒ CollectionProxy

Returns a new instance of CollectionProxy.



45
46
47
48
49
50
51
52
# File 'lib/active_entity/associations/embeds/collection_proxy.rb', line 45

def initialize(klass, association)
  @klass = klass

  @association = association

  extensions = association.extensions
  extend(*extensions) if extensions.any?
end

Instance Attribute Details

#klassObject (readonly) Also known as: model

Returns the value of attribute klass.



36
37
38
# File 'lib/active_entity/associations/embeds/collection_proxy.rb', line 36

def klass
  @klass
end

Instance Method Details

#<<(*records) ⇒ Object Also known as: push, append

Adds one or more records to the collection by setting their foreign keys to the association’s primary key. Returns self, so several appends may be chained together.

class Person < ActiveEntity::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>
#    ]


298
299
300
# File 'lib/active_entity/associations/embeds/collection_proxy.rb', line 298

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 < ActiveEntity::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


225
226
227
# File 'lib/active_entity/associations/embeds/collection_proxy.rb', line 225

def ==(other)
  records == other
end

#clearObject

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.



192
193
194
195
# File 'lib/active_entity/associations/embeds/collection_proxy.rb', line 192

def clear
  delete_all
  self
end

#concat(*records) ⇒ Object

Add 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 method calls may be chained.

class Person < ActiveEntity::Base
  has_many :pets
end

person.pets.size # => 0
person.pets.concat(Pet.new(name: 'Fancy-Fancy'))
person.pets.concat(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>
#    ]

person.pets.concat([Pet.new(name: 'Brain'), Pet.new(name: 'Benny')])
person.pets.size # => 5


146
147
148
# File 'lib/active_entity/associations/embeds/collection_proxy.rb', line 146

def concat(*records)
  @association.concat(*records)
end

#delete(*records) ⇒ Object Also known as: destroy



181
182
183
# File 'lib/active_entity/associations/embeds/collection_proxy.rb', line 181

def delete(*records)
  @association.delete(*records)
end

#delete_allObject Also known as: destroy_all



176
177
178
# File 'lib/active_entity/associations/embeds/collection_proxy.rb', line 176

def delete_all
  @association.delete_all
end

#inspectObject



76
77
78
79
80
81
82
# File 'lib/active_entity/associations/embeds/collection_proxy.rb', line 76

def inspect
  entries = records.take([size, 11].compact.min).map!(&:inspect)

  entries[10] = "..." if entries.size == 11

  "#<#{self.class.name} [#{entries.join(', ')}]>"
end

#loaded?Boolean

Returns true if the association has been loaded, otherwise false.

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

Returns:

  • (Boolean)


89
90
91
# File 'lib/active_entity/associations/embeds/collection_proxy.rb', line 89

def loaded?
  @association.loaded?
end

#prepend(*_args) ⇒ Object

Raises:

  • (NoMethodError)


304
305
306
# File 'lib/active_entity/associations/embeds/collection_proxy.rb', line 304

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

#pretty_print(q) ⇒ Object



72
73
74
# File 'lib/active_entity/associations/embeds/collection_proxy.rb', line 72

def pretty_print(q)
  q.pp(records)
end

#proxy_associationObject



197
198
199
# File 'lib/active_entity/associations/embeds/collection_proxy.rb', line 197

def proxy_association
  @association
end

#recordsObject

:nodoc:



274
275
276
# File 'lib/active_entity/associations/embeds/collection_proxy.rb', line 274

def records # :nodoc:
  @association.target
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 < ActiveEntity::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 ActiveEntity::AssociationTypeMismatch error:

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


172
173
174
# File 'lib/active_entity/associations/embeds/collection_proxy.rb', line 172

def replace(other_array)
  @association.replace(other_array)
end

#to_aryObject Also known as: to_a

: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 < ActiveEntity::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>
#    ]

Converts relation objects to Array.



269
270
271
# File 'lib/active_entity/associations/embeds/collection_proxy.rb', line 269

def to_ary
  records.dup
end