Class: ActiveRecord::Associations::AssociationCollection

Inherits:
AssociationProxy show all
Defined in:
lib/active_record/associations/association_collection.rb

Overview

:nodoc:

Instance Method Summary collapse

Methods inherited from AssociationProxy

#initialize, #loaded, #loaded?, #method_missing, #proxy_respond_to?, #reload, #respond_to?, #target, #target=

Constructor Details

This class inherits a constructor from ActiveRecord::Associations::AssociationProxy

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class ActiveRecord::Associations::AssociationProxy

Instance Method Details

#<<(*records) ⇒ Object Also known as: push, 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.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/active_record/associations/association_collection.rb', line 18

def <<(*records)
  result = true
  load_target
  @owner.transaction do
    flatten_deeper(records).each do |record|
      raise_on_type_mismatch(record)
      callback(:before_add, record)
      result &&= insert_record(record) unless @owner.new_record?
      @target << record
      callback(:after_add, record)
    end
  end
				
  result and self
end

#create(attributes = {}) ⇒ Object



62
63
64
65
66
67
68
69
70
71
# File 'lib/active_record/associations/association_collection.rb', line 62

def create(attributes = {})
  # Can't use Base.create since the foreign key may be a protected attribute.
  if attributes.is_a?(Array)
    attributes.collect { |attr| create(attr) }
  else
    record = build(attributes)
    record.save unless @owner.new_record?
    record
  end
end

#delete(*records) ⇒ Object

Remove records from this association. Does not destroy records.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/active_record/associations/association_collection.rb', line 38

def delete(*records)
  records = flatten_deeper(records)
  records.each { |record| raise_on_type_mismatch(record) }
  records.reject! { |record| @target.delete(record) if record.new_record? }
  return if records.empty?
  
  @owner.transaction do
    records.each { |record| callback(:before_remove, record) }
    delete_records(records)
    records.each do |record|
      @target.delete(record)
      callback(:after_remove, record)
    end
  end
end

#destroy_allObject



54
55
56
57
58
59
60
# File 'lib/active_record/associations/association_collection.rb', line 54

def destroy_all
  @owner.transaction do
    each { |record| record.destroy }
  end

  @target = []
end

#empty?Boolean

Returns:

  • (Boolean)


86
87
88
# File 'lib/active_record/associations/association_collection.rb', line 86

def empty?
  size.zero?
end

#lengthObject

Returns the size of the collection by loading it and calling size on the array. If you want to use this method to check whether the collection is empty, use collection.length.zero? instead of collection.empty?



82
83
84
# File 'lib/active_record/associations/association_collection.rb', line 82

def length
  load_target.size
end

#replace(other_array) ⇒ Object

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



96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/active_record/associations/association_collection.rb', line 96

def replace(other_array)
  other_array.each { |val| raise_on_type_mismatch(val) }

  load_target
  other   = other_array.size < 100 ? other_array : other_array.to_set
  current = @target.size < 100 ? @target : @target.to_set

  @owner.transaction do
    delete(@target.select { |v| !other.include?(v) })
    concat(other_array.select { |v| !current.include?(v) })
  end
end

#resetObject



11
12
13
14
# File 'lib/active_record/associations/association_collection.rb', line 11

def reset
  @target = []
  @loaded = false
end

#sizeObject

Returns the size of the collection by executing a SELECT COUNT(*) query if the collection hasn’t been loaded and calling collection.size if it has. If it’s more likely than not that the collection does have a size larger than zero and you need to fetch that collection afterwards, it’ll take one less SELECT query if you use length.



76
77
78
# File 'lib/active_record/associations/association_collection.rb', line 76

def size
  if loaded? then @target.size else count_records end
end

#to_aryObject



6
7
8
9
# File 'lib/active_record/associations/association_collection.rb', line 6

def to_ary
  load_target
  @target.to_ary
end

#uniq(collection = self) ⇒ Object



90
91
92
# File 'lib/active_record/associations/association_collection.rb', line 90

def uniq(collection = self)
  collection.inject([]) { |uniq_records, record| uniq_records << record unless uniq_records.include?(record); uniq_records }
end