Class: ActiveFedora::Associations::CollectionProxy

Inherits:
Relation
  • Object
show all
Defined in:
lib/active_fedora/associations/collection_proxy.rb

Overview

Association proxies in Active Fedora 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 ActiveFedora::Reflection::AssociationReflection.

For example, given

class Blog < ActiveFedora::Base
  has_many :posts
end

blog = Blog.find(: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 has most of the basic instance methods removed, and delegates unknown methods to @target via method_missing. As a corner case, it even removes the class method and that's why you get

blog.posts.class # => Array

though the object behind blog.posts is not an Array, but an ActiveFedora::Associations::HasManyAssociation.

The @target object is not loaded until needed. For example,

blog.posts.count

is computed directly through Solr and does not trigger by itself the instantiation of the actual post records.

Instance Attribute Summary

Attributes inherited from Relation

#default_scoped, #klass, #loaded, #values

Instance Method Summary collapse

Methods inherited from Relation

#==, #initialize_copy, #inspect, #reset, #scope_for_create, #where_values_hash

Methods included from FinderMethods

#exists?, #find_each, #find_in_batches, #find_one, #find_take, #find_with_conditions, #take

Methods included from Calculations

#calculate

Methods included from SpawnMethods

#merge, #merge!, #spawn

Methods included from QueryMethods

#build_where, #create_with_value, #extending!, #extending_values, #extending_values=, #limit, #limit!, #limit_value, #limit_value=, #none!, #offset, #offset!, #offset_value, #offset_value=, #order, #order!, #order_values, #order_values=, #where, #where!, #where_values, #where_values=

Methods included from Delegation

#method_missing

Constructor Details

#initialize(association) ⇒ CollectionProxy

:nodoc:


39
40
41
42
43
# File 'lib/active_fedora/associations/collection_proxy.rb', line 39

def initialize(association)
  @association = association
  super association.klass
  merge! association.scope
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class ActiveFedora::Delegation

Instance Method Details

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


850
851
852
# File 'lib/active_fedora/associations/collection_proxy.rb', line 850

def <<(*records)
  proxy_association.concat(records) && self
end

#any?(&block) ⇒ Boolean

Returns true if the collection is not empty.

class Person < ActiveFedora::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

You can also pass a block to define criteria. The behavior is the same, it returns true if the collection based on the criteria is not empty.

person.pets
# => [#<Pet name: "Snoop", group: "dogs">]

person.pets.any? do |pet|
  pet.group == 'cats'
end
# => false

person.pets.any? do |pet|
  pet.group == 'dogs'
end
# => true

Returns:

  • (Boolean)

783
784
785
# File 'lib/active_fedora/associations/collection_proxy.rb', line 783

def any?(&block)
  @association.any?(&block)
end

#build(attributes = {}, &block) ⇒ Object Also known as: new

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

232
233
234
# File 'lib/active_fedora/associations/collection_proxy.rb', line 232

def build(attributes = {}, &block)
  @association.build(attributes, &block)
end

#clearObject


855
856
857
858
# File 'lib/active_fedora/associations/collection_proxy.rb', line 855

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 < ActiveFedora::Base
  pets :has_many
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

306
307
308
# File 'lib/active_fedora/associations/collection_proxy.rb', line 306

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

#count(options = {}) ⇒ Object

Count all records using Solr.

class Person < ActiveFedora::Base
  has_many :pets
end

person.pets.count # => 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>
#    ]

675
676
677
# File 'lib/active_fedora/associations/collection_proxy.rb', line 675

def count(options = {})
  @association.count(options)
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>
#    ]

262
263
264
# File 'lib/active_fedora/associations/collection_proxy.rb', line 262

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)
# => ActiveFedora::RecordInvalid: Validation failed: Name can't be blank

278
279
280
# File 'lib/active_fedora/associations/collection_proxy.rb', line 278

def create!(attributes = {}, &block)
  @association.create!(attributes, &block)
end

#delete(*records) ⇒ Object

Deletes the records supplied and removes them from the collection. For has_many associations, the deletion is done according to the strategy specified by the :dependent option. Returns an array with the deleted records.

If no :dependent option is given, then it will follow the default strategy. The default strategy is :nullify. This sets the foreign keys to NULL. For, has_many :through, the default strategy is delete_all.

class Person < ActiveFedora::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 < ActiveFedora::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)
# => ActiveFedora::RecordNotFound: Couldn't find all Pets with IDs (1, 3)

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

class Person < ActiveFedora::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)
# => ActiveFedora::RecordNotFound: Couldn't find Pet with id=1

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

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

568
569
570
# File 'lib/active_fedora/associations/collection_proxy.rb', line 568

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

#delete_allObject

Deletes all the records from the collection. For has_many associations, the deletion is done according to the strategy specified by the :dependent option. Returns an array with the deleted records.

If no :dependent option is given, then it will follow the default strategy. The default strategy is :nullify. This sets the foreign keys to NULL. For, has_many :through, the default strategy is delete_all.

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

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

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

Pet.find(1, 2, 3)
# => ActiveFedora::RecordNotFound

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

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

Pet.find(1, 2, 3)
# => ActiveFedora::RecordNotFound

424
425
426
# File 'lib/active_fedora/associations/collection_proxy.rb', line 424

def delete_all
  @association.delete_all
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 < ActiveFedora::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) # => ActiveFedora::RecordNotFound: Couldn't find all Pets with IDs (1, 2, 3)

You can pass Fixnum 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) # => ActiveFedora::RecordNotFound: Couldn't find all Pets with IDs (4, 5, 6)

640
641
642
# File 'lib/active_fedora/associations/collection_proxy.rb', line 640

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

#destroy_allObject

Deletes the records of the collection directly from the database. This will always remove the records ignoring the :dependent option.

class Person < ActiveFedora::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

450
451
452
# File 'lib/active_fedora/associations/collection_proxy.rb', line 450

def destroy_all
  @association.destroy_all
end

#empty?Boolean

Returns true if the collection is empty. If the collection has been loaded or the :counter_sql option is provided, 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.length.zero?.

class Person < ActiveFedora::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

Returns:

  • (Boolean)

750
751
752
# File 'lib/active_fedora/associations/collection_proxy.rb', line 750

def empty?
  @association.empty?
end

#find(*args, &block) ⇒ Object

Finds an object in the collection responding to the id. Uses the same rules as ActiveFedora::Base.find. Returns ActiveFedora::RecordNotFound error if the object can not be found.

class Person < ActiveFedora::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) # => ActiveFedora::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>
#    ]

144
145
146
# File 'lib/active_fedora/associations/collection_proxy.rb', line 144

def find(*args, &block)
  @association.find(*args, &block)
end

#first(*args) ⇒ Object

Returns the first record, or the first 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 < ActiveFedora::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.first # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>

person.pets.first(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.first    # => nil
another_person_without.pets.first(3) # => []

174
175
176
# File 'lib/active_fedora/associations/collection_proxy.rb', line 174

def first(*args)
  @association.first(*args)
end

#include?(record) ⇒ Boolean

Returns true if the given object is present in the collection.

class Person < ActiveFedora::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

Returns:

  • (Boolean)

835
836
837
# File 'lib/active_fedora/associations/collection_proxy.rb', line 835

def include?(record)
  @association.include?(record)
end

#last(*args) ⇒ 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 < ActiveFedora::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) # => []

204
205
206
# File 'lib/active_fedora/associations/collection_proxy.rb', line 204

def last(*args)
  @association.last(*args)
end

#lengthObject

Returns the size of the collection calling size on the target. If the collection has been already loaded, length and size are equivalent. If not and you are going to need the records anyway this method will take one less query. Otherwise size is more efficient.

class Person < ActiveFedora::Base
  has_many :pets
end

person.pets.length # => 3
# queries solr for the number of matching records where "person_id_ssi" = 1

# Because the collection is loaded, you can
# call the collection with no additional queries:
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>
#    ]

728
729
730
# File 'lib/active_fedora/associations/collection_proxy.rb', line 728

def length
  @association.length
end

#load_from_solr(opts = Hash.new) ⇒ Object


53
54
55
# File 'lib/active_fedora/associations/collection_proxy.rb', line 53

def load_from_solr(opts = Hash.new)
  @association.load_from_solr(opts)
end

#load_targetObject


49
50
51
# File 'lib/active_fedora/associations/collection_proxy.rb', line 49

def load_target
  @association.load_target
end

#loaded?Boolean

Returns:

  • (Boolean)

57
58
59
# File 'lib/active_fedora/associations/collection_proxy.rb', line 57

def loaded?
  @association.loaded?
end

#many?(&block) ⇒ Boolean

Returns true if the collection has more than one record. Equivalent to collection.size > 1.

class Person < ActiveFedora::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

You can also pass a block to define criteria. The behavior is the same, it returns true if the collection based on the criteria has more than one record.

person.pets
# => [
#      #<Pet name: "Gorby", group: "cats">,
#      #<Pet name: "Puff", group: "cats">,
#      #<Pet name: "Snoop", group: "dogs">
#    ]

person.pets.many? do |pet|
  pet.group == 'dogs'
end
# => false

person.pets.many? do |pet|
  pet.group == 'cats'
end
# => true

Returns:

  • (Boolean)

821
822
823
# File 'lib/active_fedora/associations/collection_proxy.rb', line 821

def many?(&block)
  @association.many?(&block)
end

#proxy_associationObject


841
842
843
# File 'lib/active_fedora/associations/collection_proxy.rb', line 841

def proxy_association
  @association
end

#reloadObject


860
861
862
863
# File 'lib/active_fedora/associations/collection_proxy.rb', line 860

def reload
  proxy_association.reload
  self
end

#replace(other_array) ⇒ Object

Replace this collection with other_array. This will perform a diff and delete/add only records that have changed.

class Person < ActiveFedora::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 ActiveFedora::AssociationTypeMismatch error:

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

332
333
334
# File 'lib/active_fedora/associations/collection_proxy.rb', line 332

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

#select(select = nil, &block) ⇒ Object

Works in two ways.

First: Specify a subset of fields to be selected from the result set.

class Person < ActiveFedora::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.select(:name)
# => [
#      #<Pet id: nil, name: "Fancy-Fancy">,
#      #<Pet id: nil, name: "Spook">,
#      #<Pet id: nil, name: "Choo-Choo">
#    ]

person.pets.select([:id, :name])
# => [
#      #<Pet id: 1, name: "Fancy-Fancy">,
#      #<Pet id: 2, name: "Spook">,
#      #<Pet id: 3, name: "Choo-Choo">
#    ]

Be careful because this also means you’re initializing a model object with only the fields that you’ve selected. If you attempt to access a field that is not in the initialized record you’ll receive:

person.pets.select(:name).first.person_id
# => ActiveModel::MissingAttributeError: missing attribute: person_id

Second: You can pass a block so it can be used just like Array#select. This build an array of objects from the database for the scope, converting them into an array and iterating through them using Array#select.

person.pets.select { |pet| pet.name =~ /oo/ }
# => [
#      #<Pet id: 2, name: "Spook", person_id: 1>,
#      #<Pet id: 3, name: "Choo-Choo", person_id: 1>
#    ]

person.pets.select(:name) { |pet| pet.name =~ /oo/ }
# => [
#      #<Pet id: 2, name: "Spook">,
#      #<Pet id: 3, name: "Choo-Choo">
#    ]

114
115
116
# File 'lib/active_fedora/associations/collection_proxy.rb', line 114

def select(select = nil, &block)
  @association.select(select, &block)
end

#sizeObject

Returns the size of the collection. If the collection hasn't been loaded, it executes a solr query to find the matching records. 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 < ActiveFedora::Base
  has_many :pets
end

person.pets.size # => 3
# queries solr for the number of matching records where "person_id_ssi" = 1

person.pets # This will execute a solr 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 Solr count query is executed.

704
705
706
# File 'lib/active_fedora/associations/collection_proxy.rb', line 704

def size
  @association.size
end

#targetObject


45
46
47
# File 'lib/active_fedora/associations/collection_proxy.rb', line 45

def target
  @association.target
end

#to_aryObject Also known as: to_a


845
846
847
# File 'lib/active_fedora/associations/collection_proxy.rb', line 845

def to_ary
  load_target.dup
end

#uniqObject

Specifies whether the records should be unique or not.

class Person < ActiveFedora::Base
  has_many :pets
end

person.pets.select(:name)
# => [
#      #<Pet name: "Fancy-Fancy">,
#      #<Pet name: "Fancy-Fancy">
#    ]

person.pets.select(:name).uniq
# => [#<Pet name: "Fancy-Fancy">]

658
659
660
# File 'lib/active_fedora/associations/collection_proxy.rb', line 658

def uniq
  @association.uniq
end