Ticket #7352: activeresource_clone_patch_updated_for_r9089.diff
| File activeresource_clone_patch_updated_for_r9089.diff, 3.6 kB (added by thechrisoshow, 3 months ago) |
|---|
-
activeresource/test/base_test.rb
old new 508 508 end 509 509 assert_raises(ActiveResource::ResourceConflict) { Person.create(:name => 'Rick') } 510 510 end 511 512 def test_clone 513 matz = Person.find(1) 514 matz_c = matz.clone 515 assert matz_c.new? 516 matz.attributes.each do |k, v| 517 assert_equal v, matz_c.send(k) if k != Person.primary_key 518 end 519 end 520 521 def test_nested_clone 522 addy = StreetAddress.find(1, :params => {:person_id => 1}) 523 addy_c = addy.clone 524 assert addy_c.new? 525 addy.attributes.each do |k, v| 526 assert_equal v, addy_c.send(k) if k != StreetAddress.primary_key 527 end 528 assert_equal addy.prefix_options, addy_c.prefix_options 529 end 530 531 def test_complex_clone 532 matz = Person.find(1) 533 matz.address = StreetAddress.find(1, :params => {:person_id => matz.id}) 534 matz.non_ar_hash = {:not => "an ARes instance"} 535 matz.non_ar_arr = ["not", "ARes"] 536 matz_c = matz.clone 537 assert matz_c.new? 538 assert_raises(NoMethodError) {matz_c.address} 539 assert_equal matz.non_ar_hash, matz_c.non_ar_hash 540 assert_equal matz.non_ar_arr, matz_c.non_ar_arr 541 542 # Test that actual copy, not just reference copy 543 matz.non_ar_hash[:not] = "changed" 544 assert_not_equal matz.non_ar_hash, matz_c.non_ar_hash 545 end 511 546 512 547 def test_update 513 548 matz = Person.find(:first) -
activeresource/lib/active_resource/base.rb
old new 605 605 @prefix_options = {} 606 606 load(attributes) 607 607 end 608 609 # Returns a clone of the resource that hasn't been assigned an id yet and 610 # is treated as a new resource. 611 # 612 # ryan = Person.find(1) 613 # not_ryan = ryan.clone 614 # not_ryan.new? # => true 615 # 616 # Any active resource member attributes will NOT be cloned, though all other 617 # attributes are. This is to prevent the conflict between any prefix_options 618 # that refer to the original parent resource and the newly cloned parent 619 # resource that does not exist. 620 # 621 # ryan = Person.find(1) 622 # ryan.address = StreetAddress.find(1, :person_id => ryan.id) 623 # ryan.hash = {:not => "an ARes instance"} 624 # 625 # not_ryan = ryan.clone 626 # not_ryan.new? # => true 627 # not_ryan.address # => NoMethodError 628 # not_ryan.hash # => {:not => "an ARes instance"} 629 # 630 def clone 631 # Clone all attributes except the pk and any nested ARes 632 attrs = self.attributes.reject {|k,v| k == self.class.primary_key || v.is_a?(ActiveResource::Base)}.inject({}) do |attrs, (k, v)| 633 attrs[k] = v.clone 634 attrs 635 end 636 # Form the new resource - bypass initialize of resource with 'new' as that will call 'load' which 637 # attempts to convert hashes into member objects and arrays into collections of objects. We want 638 # the raw objects to be cloned so we bypass load by directly setting the attributes hash. 639 resource = self.class.new({}) 640 resource.prefix_options = self.prefix_options 641 resource.send :instance_variable_set, '@attributes', attrs 642 resource 643 end 608 644 645 609 646 # A method to determine if the resource a new object (i.e., it has not been POSTed to the remote service yet). 610 647 # 611 648 # ==== Examples