Class | DataMapper::Associations::HasAndBelongsToManyAssociation::Set |
In: |
lib/data_mapper/associations/has_and_belongs_to_many_association.rb
lib/data_mapper/associations/has_and_belongs_to_many_association.rb |
Parent: | Associations::Reference |
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 284 284: def <<(member) 285: return nil unless member 286: 287: if member.is_a?(Enumerable) 288: member.each { |entry| entries << entry } 289: else 290: entries << member 291: end 292: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 284 284: def <<(member) 285: return nil unless member 286: 287: if member.is_a?(Enumerable) 288: member.each { |entry| entries << entry } 289: else 290: entries << member 291: end 292: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 221 221: def [](key) 222: entries[key] 223: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 221 221: def [](key) 222: entries[key] 223: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 294 294: def clear 295: @entries = Support::TypedSet.new(association.constant) 296: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 294 294: def clear 295: @entries = Support::TypedSet.new(association.constant) 296: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 217 217: def count 218: entries.size 219: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 217 217: def count 218: entries.size 219: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 401 401: def deactivate 402: case association.dependency 403: when :destroy 404: entries.each do |member| 405: member.destroy! unless member.new_record? 406: end 407: when :delete 408: delete_association 409: when :protect 410: unless entries.empty? 411: raise AssociationProtectedError.new("You cannot delete this model while it has items associated with it.") 412: end 413: when :nullify 414: nullify_association 415: else 416: nullify_association 417: end 418: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 401 401: def deactivate 402: case association.dependency 403: when :destroy 404: entries.each do |member| 405: member.destroy! unless member.new_record? 406: end 407: when :delete 408: delete_association 409: when :protect 410: unless entries.empty? 411: raise AssociationProtectedError.new("You cannot delete this model while it has items associated with it.") 412: end 413: when :nullify 414: nullify_association 415: else 416: nullify_association 417: end 418: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 302 302: def delete(member) 303: if found_member = entries.detect { |entry| entry == member } 304: entries.delete?(found_member) 305: @instance.database_context.adapter.connection do |db| 306: command = db.create_command(association.to_delete_member_sql) 307: command.execute_non_query(@instance.key, member.key) 308: end 309: member 310: else 311: nil 312: end 313: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 302 302: def delete(member) 303: if found_member = entries.detect { |entry| entry == member } 304: entries.delete?(found_member) 305: @instance.database_context.adapter.connection do |db| 306: command = db.create_command(association.to_delete_member_sql) 307: command.execute_non_query(@instance.key, member.key) 308: end 309: member 310: else 311: nil 312: end 313: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 420 420: def delete_association 421: @instance.database_context.adapter.connection do |db| 422: associated_keys = entries.collect do |item| 423: item.key unless item.new_record? 424: end.compact 425: parameters = [@instance.key] + associated_keys 426: 427: sql = association.to_delete_set_sql 428: db.create_command(sql).execute_non_query(*[parameters, parameters]) 429: 430: sql = association.to_delete_members_sql 431: db.create_command(sql).execute_non_query(associated_keys) 432: end 433: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 420 420: def delete_association 421: @instance.database_context.adapter.connection do |db| 422: associated_keys = entries.collect do |item| 423: item.key unless item.new_record? 424: end.compact 425: parameters = [@instance.key] + associated_keys 426: 427: sql = association.to_delete_set_sql 428: db.create_command(sql).execute_non_query(*[parameters, parameters]) 429: 430: sql = association.to_delete_members_sql 431: db.create_command(sql).execute_non_query(associated_keys) 432: end 433: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 229 229: def dirty?(cleared = ::Set.new) 230: return false unless @entries 231: @entries.any? {|item| cleared.include?(item) || item.dirty?(cleared) } || @associated_keys != @entries.map { |entry| entry.keys } 232: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 229 229: def dirty?(cleared = ::Set.new) 230: return false unless @entries 231: @entries.any? {|item| cleared.include?(item) || item.dirty?(cleared) } || @associated_keys != @entries.map { |entry| entry.keys } 232: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 208 208: def each 209: entries.each { |item| yield item } 210: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 208 208: def each 209: entries.each { |item| yield item } 210: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 225 225: def empty? 226: entries.empty? 227: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 225 225: def empty? 226: entries.empty? 227: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 331 331: def entries 332: @entries || @entries = begin 333: 334: if @instance.loaded_set.nil? 335: Support::TypedSet.new(association.constant) 336: else 337: 338: associated_items = Hash.new { |h,k| h[k] = [] } 339: left_key_index = nil 340: association_constant = association.constant 341: left_foreign_key = association.left_foreign_key 342: 343: matcher = lambda do |instance,columns,row| 344: 345: # Locate the column for the left-key. 346: unless left_key_index 347: columns.each_with_index do |column, index| 348: if column.name == association.left_foreign_key.name 349: left_key_index = index 350: break 351: end 352: end 353: end 354: 355: if instance.kind_of?(association_constant) 356: associated_items[left_foreign_key.type_cast_value(row[left_key_index])] << instance 357: end 358: end 359: 360: @instance.database_context.all(association.constant, 361: left_foreign_key => @instance.loaded_set.map(&:key), 362: :shallow_include => association.foreign_name, 363: :intercept_load => matcher 364: ) 365: 366: # do stsuff with associated_items hash. 367: setter_method = "#{@association_name}=".to_sym 368: 369: @instance.loaded_set.each do |entry| 370: entry.send(setter_method, associated_items[entry.key]) if entry.respond_to?(setter_method) 371: end # @instance.loaded_set.each 372: 373: @entries 374: end 375: end 376: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 331 331: def entries 332: @entries || @entries = begin 333: 334: if @instance.loaded_set.nil? 335: Support::TypedSet.new(association.constant) 336: else 337: 338: associated_items = Hash.new { |h,k| h[k] = [] } 339: left_key_index = nil 340: association_constant = association.constant 341: left_foreign_key = association.left_foreign_key 342: 343: matcher = lambda do |instance,columns,row| 344: 345: # Locate the column for the left-key. 346: unless left_key_index 347: columns.each_with_index do |column, index| 348: if column.name == association.left_foreign_key.name 349: left_key_index = index 350: break 351: end 352: end 353: end 354: 355: if instance.kind_of?(association_constant) 356: associated_items[left_foreign_key.type_cast_value(row[left_key_index])] << instance 357: end 358: end 359: 360: @instance.database_context.all(association.constant, 361: left_foreign_key => @instance.loaded_set.map(&:key), 362: :shallow_include => association.foreign_name, 363: :intercept_load => matcher 364: ) 365: 366: # do stsuff with associated_items hash. 367: setter_method = "#{@association_name}=".to_sym 368: 369: @instance.loaded_set.each do |entry| 370: entry.send(setter_method, associated_items[entry.key]) if entry.respond_to?(setter_method) 371: end # @instance.loaded_set.each 372: 373: @entries 374: end 375: end 376: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 393 393: def first 394: entries.entries.first 395: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 393 393: def first 394: entries.entries.first 395: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 389 389: def inspect 390: entries.inspect 391: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 389 389: def inspect 390: entries.inspect 391: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 397 397: def last 398: entries.entries.last 399: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 397 397: def last 398: entries.entries.last 399: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 315 315: def method_missing(symbol, *args, &block) 316: if entries.respond_to?(symbol) 317: entries.send(symbol, *args, &block) 318: elsif association.associated_table.associations.any? { |assoc| assoc.name == symbol } 319: results = [] 320: each do |item| 321: unless (val = item.send(symbol)).blank? 322: results << (val.is_a?(Enumerable) ? val.entries : val) 323: end 324: end 325: results.flatten 326: else 327: super 328: end 329: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 315 315: def method_missing(symbol, *args, &block) 316: if entries.respond_to?(symbol) 317: entries.send(symbol, *args, &block) 318: elsif association.associated_table.associations.any? { |assoc| assoc.name == symbol } 319: results = [] 320: each do |item| 321: unless (val = item.send(symbol)).blank? 322: results << (val.is_a?(Enumerable) ? val.entries : val) 323: end 324: end 325: results.flatten 326: else 327: super 328: end 329: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 435 435: def nullify_association 436: @instance.database_context.adapter.connection do |db| 437: sql = association.to_delete_sql 438: parameters = [@instance.key] 439: db.create_command(sql).execute_non_query(*parameters) 440: end 441: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 435 435: def nullify_association 436: @instance.database_context.adapter.connection do |db| 437: sql = association.to_delete_sql 438: parameters = [@instance.key] 439: db.create_command(sql).execute_non_query(*parameters) 440: end 441: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 298 298: def reload! 299: @entries = nil 300: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 298 298: def reload! 299: @entries = nil 300: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 238 238: def save_without_validation(database_context, cleared) 239: unless @entries.nil? 240: 241: if dirty?(cleared) 242: adapter = @instance.database_context.adapter 243: 244: adapter.connection do |db| 245: command = db.create_command(association.to_delete_sql) 246: command.execute_non_query(@instance.key) 247: end 248: 249: unless @entries.empty? 250: if adapter.batch_insertable? 251: sql = association.to_insert_sql 252: values = [] 253: keys = [] 254: 255: @entries.each do |member| 256: adapter.save_without_validation(database_context, member, cleared) 257: values << "(?, ?)" 258: keys << @instance.key << member.key 259: end 260: 261: adapter.connection do |db| 262: command = db.create_command(sql << ' ' << values.join(', ')) 263: command.execute_non_query(*keys) 264: end 265: 266: else # adapter doesn't support batch inserts... 267: @entries.each do |member| 268: adapter.save_without_validation(database_context, member, cleared) 269: end 270: 271: # Just to keep the same flow as the batch-insert mode. 272: @entries.each do |member| 273: adapter.connection do |db| 274: command = db.create_command("#{association.to_insert_sql} (?, ?)") 275: command.execute_non_query(@instance.key, member.key) 276: end 277: end 278: end # if adapter.batch_insertable? 279: end # unless @entries.empty? 280: end # if dirty? 281: end 282: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 238 238: def save_without_validation(database_context, cleared) 239: unless @entries.nil? 240: 241: if dirty?(cleared) 242: adapter = @instance.database_context.adapter 243: 244: adapter.connection do |db| 245: command = db.create_command(association.to_delete_sql) 246: command.execute_non_query(@instance.key) 247: end 248: 249: unless @entries.empty? 250: if adapter.batch_insertable? 251: sql = association.to_insert_sql 252: values = [] 253: keys = [] 254: 255: @entries.each do |member| 256: adapter.save_without_validation(database_context, member, cleared) 257: values << "(?, ?)" 258: keys << @instance.key << member.key 259: end 260: 261: adapter.connection do |db| 262: command = db.create_command(sql << ' ' << values.join(', ')) 263: command.execute_non_query(*keys) 264: end 265: 266: else # adapter doesn't support batch inserts... 267: @entries.each do |member| 268: adapter.save_without_validation(database_context, member, cleared) 269: end 270: 271: # Just to keep the same flow as the batch-insert mode. 272: @entries.each do |member| 273: adapter.connection do |db| 274: command = db.create_command("#{association.to_insert_sql} (?, ?)") 275: command.execute_non_query(@instance.key, member.key) 276: end 277: end 278: end # if adapter.batch_insertable? 279: end # unless @entries.empty? 280: end # if dirty? 281: end 282: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 378 378: def set(results) 379: if results.is_a?(Support::TypedSet) 380: @entries = results 381: else 382: @entries = Support::TypedSet.new(association.constant) 383: [*results].each { |item| @entries << item } 384: end 385: @associated_keys = @entries.map { |entry| entry.key } 386: return @entries 387: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 378 378: def set(results) 379: if results.is_a?(Support::TypedSet) 380: @entries = results 381: else 382: @entries = Support::TypedSet.new(association.constant) 383: [*results].each { |item| @entries << item } 384: end 385: @associated_keys = @entries.map { |entry| entry.key } 386: return @entries 387: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 212 212: def size 213: entries.size 214: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 212 212: def size 213: entries.size 214: end
# File lib/data_mapper/associations/has_and_belongs_to_many_association.rb, line 234 234: def validate_recursively(event, cleared) 235: @entries.blank? || @entries.all? { |item| cleared.include?(item) || item.validate_recursively(event, cleared) } 236: end