Ticket #7352: activeresource_clone_patch.diff
| File activeresource_clone_patch.diff, 3.3 kB (added by rwdaigle, 1 year ago) |
|---|
-
test/base_test.rb
old new 230 230 assert_raises(ActiveResource::ResourceConflict) { Person.create(:name => 'Rick') } 231 231 end 232 232 233 def test_clone 234 matz = Person.find(1) 235 matz_c = matz.clone 236 assert matz_c.new? 237 matz.attributes.each do |k, v| 238 assert_equal v, matz_c.send(k) if k != Person.primary_key 239 end 240 end 241 242 def test_nested_clone 243 addy = StreetAddress.find(1, :person_id => 1) 244 addy_c = addy.clone 245 assert addy_c.new? 246 addy.attributes.each do |k, v| 247 assert_equal v, addy_c.send(k) if k != StreetAddress.primary_key 248 end 249 assert_equal addy.prefix_options, addy_c.prefix_options 250 end 251 252 def test_complex_clone 253 matz = Person.find(1) 254 matz.address = StreetAddress.find(1, :person_id => matz.id) 255 matz.non_ar_hash = {:not => "an ARes instance"} 256 matz.non_ar_arr = ["not", "ARes"] 257 matz_c = matz.clone 258 assert matz_c.new? 259 assert_raises(NoMethodError) {matz_c.address} 260 assert_equal matz.non_ar_hash, matz_c.non_ar_hash 261 assert_equal matz.non_ar_arr, matz_c.non_ar_arr 262 263 # Test that actual copy, not just reference copy 264 matz.non_ar_hash[:not] = "changed" 265 assert_not_equal matz.non_ar_hash, matz_c.non_ar_hash 266 end 267 233 268 def test_update 234 269 matz = Person.find(:first) 235 270 matz.name = "David" -
lib/active_resource/base.rb
old new 165 165 @prefix_options = prefix_options 166 166 end 167 167 168 # Returns a clone of the resource that hasn't been assigned an id yet and 169 # is treated as a new resource. 170 # 171 # ryan = Person.find(1) 172 # not_ryan = ryan.clone 173 # not_ryan.new? # => true 174 # 175 # Any active resource member attributes will NOT be cloned, though all other 176 # attributes are. This is to prevent the conflict between any prefix_options 177 # that refer to the original parent resource and the newly cloned parent 178 # resource that does not exist. 179 # 180 # ryan = Person.find(1) 181 # ryan.address = StreetAddress.find(1, :person_id => ryan.id) 182 # ryan.hash = {:not => "an ARes instance"} 183 # 184 # not_ryan = ryan.clone 185 # not_ryan.new? # => true 186 # not_ryan.address # => NoMethodError 187 # not_ryan.hash # => {:not => "an ARes instance"} 188 # 189 def clone 190 191 # Clone all attributes except the pk and any nested ARes 192 attrs = self.attributes.reject {|k,v| k == self.class.primary_key || v.is_a?(ActiveResource::Base)}.inject({}) do |attrs, (k, v)| 193 attrs[k] = v.clone 194 attrs 195 end 196 197 # Form the new resource - bypass initialize of resource with 'new' as that will call 'load' which 198 # attempts to convert hashes into member objects and arrays into collections of objects. We want 199 # the raw objects to be cloned so we bypass load by directly setting the attributes hash. 200 resource = self.class.new({}, self.prefix_options) 201 resource.send :instance_variable_set, '@attributes', attrs 202 resource 203 end 204 168 205 # Is the resource a new object? 169 206 def new? 170 207 id.nil?