Class: ActiveRecord::Associations::AssociationCollection
Public Instance Methods
<< (*records)
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.
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 18 18: def <<(*records) 19: result = true 20: load_target if @owner.new_record? 21: 22: @owner.transaction do 23: flatten_deeper(records).each do |record| 24: raise_on_type_mismatch(record) 25: callback(:before_add, record) 26: result &&= insert_record(record) unless @owner.new_record? 27: @target << record 28: callback(:after_add, record) 29: end 30: end 31: 32: result && self 33: end
any? () {|*block_args| ...}
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 128 128: def any? 129: if block_given? 130: method_missing(:any?) { |*block_args| yield(*block_args) } 131: else 132: !empty? 133: end 134: end
clear ()
Removes all records from this association. Returns self so method calls may be chained.
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 72 72: def clear 73: return self if length.zero? # forces load_target if it hasn't happened already 74: 75: if @reflection.options[:dependent] && @reflection.options[:dependent] == :destroy 76: destroy_all 77: else 78: delete_all 79: end 80: 81: self 82: end
concat (*records)
Alias for #<<
create (attrs = {})
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 92 92: def create(attrs = {}) 93: if attrs.is_a?(Array) 94: attrs.collect { |attr| create(attr) } 95: else 96: create_record(attrs) { |record| record.save } 97: end 98: end
create! (attrs = {})
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 100 100: def create!(attrs = {}) 101: create_record(attrs) { |record| record.save! } 102: end
delete (*records)
Remove records from this association. Does not destroy records.
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 55 55: def delete(*records) 56: records = flatten_deeper(records) 57: records.each { |record| raise_on_type_mismatch(record) } 58: records.reject! { |record| @target.delete(record) if record.new_record? } 59: return if records.empty? 60: 61: @owner.transaction do 62: records.each { |record| callback(:before_remove, record) } 63: delete_records(records) 64: records.each do |record| 65: @target.delete(record) 66: callback(:after_remove, record) 67: end 68: end 69: end
delete_all ()
Remove all records from this association
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 39 39: def delete_all 40: load_target 41: delete(@target) 42: reset_target! 43: end
destroy_all ()
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 84 84: def destroy_all 85: @owner.transaction do 86: each { |record| record.destroy } 87: end 88: 89: reset_target! 90: end
empty? ()
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 124 124: def empty? 125: size.zero? 126: end
include? (record)
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 162 162: def include?(record) 163: return false unless record.is_a?(@reflection.klass) 164: return @target.include?(record) if loaded? 165: exists?(record) 166: end
length ()
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?
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 120 120: def length 121: load_target.size 122: end
push (*records)
Alias for #<<
replace (other_array)
Replace this collection with other_array This will perform a diff and delete/add only records that have changed.
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 149 149: def replace(other_array) 150: other_array.each { |val| raise_on_type_mismatch(val) } 151: 152: load_target 153: other = other_array.size < 100 ? other_array : other_array.to_set 154: current = @target.size < 100 ? @target : @target.to_set 155: 156: @owner.transaction do 157: delete(@target.select { |v| !other.include?(v) }) 158: concat(other_array.select { |v| !current.include?(v) }) 159: end 160: end
reset ()
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 11 11: def reset 12: reset_target! 13: @loaded = false 14: end
size ()
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.
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 107 107: def size 108: if @owner.new_record? || (loaded? && !@reflection.options[:uniq]) 109: @target.size 110: elsif !loaded? && !@reflection.options[:uniq] && @target.is_a?(Array) 111: unsaved_records = Array(@target.detect { |r| r.new_record? }) 112: unsaved_records.size + count_records 113: else 114: count_records 115: end 116: end
sum (*args) {|*block_args| ...}
Calculate sum using SQL, not Enumerable
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 46 46: def sum(*args) 47: if block_given? 48: calculate(:sum, *args) { |*block_args| yield(*block_args) } 49: else 50: calculate(:sum, *args) 51: end 52: end
to_ary ()
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 6 6: def to_ary 7: load_target 8: @target.to_ary 9: end
uniq (collection = self)
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 136 136: def uniq(collection = self) 137: seen = Set.new 138: collection.inject([]) do |kept, record| 139: unless seen.include?(record.id) 140: kept << record 141: seen << record.id 142: end 143: kept 144: end 145: end
Protected Instance Methods
construct_scope ()
overloaded in derived Association classes to provide useful scoping depending on association type.
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 190 190: def construct_scope 191: {} 192: end
find_target ()
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 198 198: def find_target 199: records = 200: if @reflection.options[:finder_sql] 201: @reflection.klass.find_by_sql(@finder_sql) 202: else 203: find(:all) 204: end 205: 206: @reflection.options[:uniq] ? uniq(records) : records 207: end
method_missing (method, *args) {|*block_args| ...}
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 169 169: def method_missing(method, *args) 170: if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method)) 171: if block_given? 172: super { |*block_args| yield(*block_args) } 173: else 174: super 175: end 176: elsif @reflection.klass.scopes.include?(method) 177: @reflection.klass.scopes[method].call(self, *args) 178: else 179: with_scope(construct_scope) do 180: if block_given? 181: @reflection.klass.send(method, *args) { |*block_args| yield(*block_args) } 182: else 183: @reflection.klass.send(method, *args) 184: end 185: end 186: end 187: end
reset_target! ()
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 194 194: def reset_target! 195: @target = Array.new 196: end
Private Instance Methods
add_record_to_target_with_callbacks (record) {|record| ...}
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 232 232: def add_record_to_target_with_callbacks(record) 233: callback(:before_add, record) 234: yield(record) if block_given? 235: @target ||= [] unless loaded? 236: @target << record 237: callback(:after_add, record) 238: record 239: end
build_record (attrs) {|*block_args| ...}
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 222 222: def build_record(attrs) 223: attrs.update(@reflection.options[:conditions]) if @reflection.options[:conditions].is_a?(Hash) 224: record = @reflection.klass.new(attrs) 225: if block_given? 226: add_record_to_target_with_callbacks(record) { |*block_args| yield(*block_args) } 227: else 228: add_record_to_target_with_callbacks(record) 229: end 230: end
callback (method, record)
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 241 241: def callback(method, record) 242: callbacks_for(method).each do |callback| 243: case callback 244: when Symbol 245: @owner.send(callback, record) 246: when Proc, Method 247: callback.call(@owner, record) 248: else 249: if callback.respond_to?(method) 250: callback.send(method, @owner, record) 251: else 252: raise ActiveRecordError, "Callbacks must be a symbol denoting the method to call, a string to be evaluated, a block to be invoked, or an object responding to the callback method." 253: end 254: end 255: end 256: end
callbacks_for (callback_name)
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 258 258: def callbacks_for(callback_name) 259: full_callback_name = "#{callback_name}_for_#{@reflection.name}" 260: @owner.class.read_inheritable_attribute(full_callback_name.to_sym) || [] 261: end
create_record (attrs) {|*block_args| ...}
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 211 211: def create_record(attrs) 212: attrs.update(@reflection.options[:conditions]) if @reflection.options[:conditions].is_a?(Hash) 213: ensure_owner_is_not_new 214: record = @reflection.klass.send(:with_scope, :create => construct_scope[:create]) { @reflection.klass.new(attrs) } 215: if block_given? 216: add_record_to_target_with_callbacks(record) { |*block_args| yield(*block_args) } 217: else 218: add_record_to_target_with_callbacks(record) 219: end 220: end
ensure_owner_is_not_new ()
# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 263 263: def ensure_owner_is_not_new 264: if @owner.new_record? 265: raise ActiveRecord::RecordNotSaved, "You cannot call create unless the parent is saved" 266: end 267: end