Class: ActiveRecord::Associations::AssociationCollection

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

Overview

:nodoc:

Instance Attribute Summary

Attributes inherited from AssociationProxy

#reflection

Instance Method Summary collapse

Methods inherited from AssociationProxy

#===, #aliased_table_name, #conditions, #initialize, #loaded, #loaded?, #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
33
# 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 && self
end

#clearObject

Removes all records from this association. Returns self so method calls may be chained.



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

def clear
  return self if length.zero? # forces load_target if hasn't happened already

  if @reflection.options[:dependent] && @reflection.options[:dependent] == :delete_all
    destroy_all
  else          
    delete_all
  end

  self
end

#create(attributes = {}) ⇒ Object



83
84
85
86
87
88
89
90
91
92
# File 'lib/active_record/associations/association_collection.rb', line 83

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.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/active_record/associations/association_collection.rb', line 46

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

#delete_allObject

Remove all records from this association



39
40
41
42
43
# File 'lib/active_record/associations/association_collection.rb', line 39

def delete_all
  load_target
  delete(@target)
  @target = []
end

#destroy_allObject



75
76
77
78
79
80
81
# File 'lib/active_record/associations/association_collection.rb', line 75

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

  @target = []
end

#empty?Boolean

Returns:

  • (Boolean)


107
108
109
# File 'lib/active_record/associations/association_collection.rb', line 107

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?



103
104
105
# File 'lib/active_record/associations/association_collection.rb', line 103

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.



117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/active_record/associations/association_collection.rb', line 117

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.



97
98
99
# File 'lib/active_record/associations/association_collection.rb', line 97

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



111
112
113
# File 'lib/active_record/associations/association_collection.rb', line 111

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