Class: ActiveRecord::Associations::AssociationCollection
- Inherits:
-
AssociationProxy
- Object
- AssociationProxy
- ActiveRecord::Associations::AssociationCollection
- Defined in:
- lib/activerecord/lib/active_record/associations/association_collection.rb
Overview
:nodoc:
Direct Known Subclasses
Instance Method Summary collapse
-
#<<(*records) ⇒ Object
Add
records
to this association. -
#clear ⇒ Object
Removes all records from this association.
-
#delete(*records) ⇒ Object
Remove
records
from this association. - #find(*args) ⇒ Object
-
#size ⇒ Object
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.
Instance Method Details
#<<(*records) ⇒ Object
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.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/activerecord/lib/active_record/associations/association_collection.rb', line 53 def <<(*records) result = true load_target if @owner.new_record? @owner.transaction do flatten_deeper(records).each do |record| raise_on_type_mismatch(record) add_record_to_target_with_callbacks(record) do |r| result &&= insert_record(record) unless @owner.new_record? end end end @owner.send(:cache_write, @reflection, self) if @reflection.[:cached] result && self end |
#clear ⇒ Object
Removes all records from this association. Returns self
so method calls may be chained.
92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/activerecord/lib/active_record/associations/association_collection.rb', line 92 def clear return self if length.zero? # forces load_target if it hasn't happened already if @reflection.[:dependent] && @reflection.[:dependent] == :destroy destroy_all else delete_all end @owner.send(:cache_write, @reflection, self) if @reflection.[:cached] self end |
#delete(*records) ⇒ Object
Remove records
from this association. Does not destroy records
.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/activerecord/lib/active_record/associations/association_collection.rb', line 72 def delete(*records) records = flatten_deeper(records) records.each { |record| raise_on_type_mismatch(record) } @owner.transaction do records.each { |record| callback(:before_remove, record) } old_records = records.reject {|r| r.new_record? } delete_records(old_records) if old_records.any? records.each do |record| @target.delete(record) callback(:after_remove, record) end end @owner.send(:cache_write, @reflection, self) if @reflection.[:cached] end |
#find(*args) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/activerecord/lib/active_record/associations/association_collection.rb', line 6 def find(*args) = args. expects_array = args.first.kind_of?(Array) args = args.flatten.compact.uniq if @reflection.[:cached] && !args.first.is_a?(Symbol) result = self.select { |record| args.map(&:to_i).include? record.id } return expects_array ? result : result.first end # If using a custom finder_sql, scan the entire collection. if @reflection.[:finder_sql] ids = args.flatten.compact.uniq.map(&:to_i) if ids.size == 1 id = ids.first record = load_target.detect { |r| id == r.id } expects_array ? [ record ] : record else load_target.select { |r| ids.include?(r.id) } end else conditions = "#{@finder_sql}" if sanitized_conditions = sanitize_sql([:conditions]) conditions << " AND (#{sanitized_conditions})" end [:conditions] = conditions if [:order] && @reflection.[:order] [:order] = "#{[:order]}, #{@reflection.[:order]}" elsif @reflection.[:order] [:order] = @reflection.[:order] end # Build options specific to association () () # Pass through args exactly as we received them. args << @reflection.klass.find(*args) end end |
#size ⇒ Object
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.
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/activerecord/lib/active_record/associations/association_collection.rb', line 109 def size if @reflection.[:cached] returning result = self.to_ary do @reflection.[:uniq] ? result.uniq.size : result.size end end if @owner.new_record? || (loaded? && !@reflection.[:uniq]) @target.size elsif !loaded? && !@reflection.[:uniq] && @target.is_a?(Array) unsaved_records = @target.select { |r| r.new_record? } unsaved_records.size + count_records else count_records end end |