From c97f329b2a76439cd4fe71debdd64c71e9890b48 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 19 Apr 2007 22:18:03 +0000 Subject: Disregard namespaces from the default element name, so Highrise::Person will just try to fetch from "/people", not "/highrise/people" [DHH] Added that saves which get a body response (and not just a 201) will use that response to update themselves [DHH] Fixed constant warning when fetching the same object multiple times [DHH] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@6539 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activeresource/CHANGELOG | 6 ++++++ activeresource/lib/active_resource/base.rb | 19 ++++++++++++++----- activeresource/lib/active_resource/connection.rb | 13 +++++++++++-- activeresource/lib/active_resource/http_mock.rb | 2 +- activeresource/test/base_test.rb | 15 +++++---------- activeresource/test/connection_test.rb | 2 +- 6 files changed, 38 insertions(+), 19 deletions(-) diff --git a/activeresource/CHANGELOG b/activeresource/CHANGELOG index c5d11d2c63..ee4fc90298 100644 --- a/activeresource/CHANGELOG +++ b/activeresource/CHANGELOG @@ -1,5 +1,11 @@ *SVN* +* Fixed constant warning when fetching the same object multiple times [DHH] + +* Added that saves which get a body response (and not just a 201) will use that response to update themselves [DHH] + +* Disregard namespaces from the default element name, so Highrise::Person will just try to fetch from "/people", not "/highrise/people" [DHH] + * Allow array and hash query parameters. #7756 [Greg Spurrier] * Loading a resource preserves its prefix_options. #7353 [Ryan Daigle] diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb index 68ce7e080a..585531049a 100644 --- a/activeresource/lib/active_resource/base.rb +++ b/activeresource/lib/active_resource/base.rb @@ -29,7 +29,10 @@ module ActiveResource @connection end - attr_accessor_with_default(:element_name) { to_s.underscore } #:nodoc: + # Do not include any modules in the default element name. This makes it easier to seclude ARes objects + # in a separate namespace without having to set element_name repeatedly. + attr_accessor_with_default(:element_name) { to_s.split("::").last.underscore } #:nodoc: + attr_accessor_with_default(:collection_name) { element_name.pluralize } #:nodoc: attr_accessor_with_default(:primary_key, 'id') #:nodoc: @@ -149,7 +152,7 @@ module ActiveResource def initialize(attributes = {}, prefix_options = {}) @attributes = {} - self.load attributes + load(attributes) @prefix_options = prefix_options end @@ -184,7 +187,9 @@ module ActiveResource id.hash end - # Delegates to +create+ if a new object, +update+ if its old. + # Delegates to +create+ if a new object, +update+ if its old. If the response to the save includes a body, + # it will be assumed that this body is XML for the final object as it looked after the save (which would include + # attributes like created_at that wasn't part of the original submit). def save new? ? create : update end @@ -206,7 +211,7 @@ module ActiveResource # Reloads the attributes of this object from the remote web service. def reload - self.load self.class.find(id, @prefix_options).attributes + self.load(self.class.find(id, @prefix_options).attributes) end # Manually load attributes from a hash. Recursively loads collections of @@ -245,6 +250,10 @@ module ActiveResource def create returning connection.post(collection_path, to_xml) do |response| self.id = id_from_response(response) + + if response['Content-size'] != "0" && response.body.strip.size > 0 + load(connection.xml_from_response(response)) + end end end @@ -270,7 +279,7 @@ module ActiveResource # Tries to find a resource for a given name; if it fails, then the resource is created def find_or_create_resource_for(name) resource_name = name.to_s.camelize - resource_name.constantize + self.class.const_get(resource_name) rescue NameError resource = self.class.const_set(resource_name, Class.new(ActiveResource::Base)) resource.prefix = self.class.prefix diff --git a/activeresource/lib/active_resource/connection.rb b/activeresource/lib/active_resource/connection.rb index 8e25ec5eb6..c37bb73834 100644 --- a/activeresource/lib/active_resource/connection.rb +++ b/activeresource/lib/active_resource/connection.rb @@ -52,7 +52,7 @@ module ActiveResource # Execute a GET request. # Used to get (find) resources. def get(path) - from_xml_data(Hash.from_xml(request(:get, path, build_request_headers).body).values.first) + xml_from_response(request(:get, path, build_request_headers)) end # Execute a DELETE request (see HTTP protocol documentation if unfamiliar). @@ -73,6 +73,15 @@ module ActiveResource request(:post, path, body, build_request_headers) end + def xml_from_response(response) + if response = from_xml_data(Hash.from_xml(response.body)) + response.first + else + nil + end + end + + private # Makes request to remote service. def request(method, path, *arguments) @@ -138,7 +147,7 @@ module ActiveResource case data.values.first when Hash then [ from_xml_data(data.values.first) ] when Array then from_xml_data(data.values.first) - else data + else data.values.first end else data.each_key { |key| data[key] = from_xml_data(data[key]) } diff --git a/activeresource/lib/active_resource/http_mock.rb b/activeresource/lib/active_resource/http_mock.rb index 3ce31a50ea..90823babd1 100644 --- a/activeresource/lib/active_resource/http_mock.rb +++ b/activeresource/lib/active_resource/http_mock.rb @@ -12,7 +12,7 @@ module ActiveResource for method in [ :post, :put, :get, :delete ] module_eval <<-EOE def #{method}(path, request_headers = {}, body = nil, status = 200, response_headers = {}) - @responses[Request.new(:#{method}, path, nil, request_headers)] = Response.new(body || {}, status, response_headers) + @responses[Request.new(:#{method}, path, nil, request_headers)] = Response.new(body || "", status, response_headers) end EOE end diff --git a/activeresource/test/base_test.rb b/activeresource/test/base_test.rb index c3ae05a1ae..a0e38c991d 100644 --- a/activeresource/test/base_test.rb +++ b/activeresource/test/base_test.rb @@ -16,8 +16,8 @@ class BaseTest < Test::Unit::TestCase mock.put "/people/1.xml", {}, nil, 204 mock.delete "/people/1.xml", {}, nil, 200 mock.delete "/people/2.xml", {}, nil, 400 - mock.post "/people.xml", {}, nil, 201, 'Location' => '/people/5.xml' mock.get "/people/99.xml", {}, nil, 404 + mock.post "/people.xml", {}, "Rick25", 201, 'Location' => '/people/5.xml' mock.get "/people.xml", {}, "#{@matz}#{@david}" mock.get "/people/1/addresses.xml", {}, "#{@addy}" mock.get "/people/1/addresses/1.xml", {}, @addy @@ -128,14 +128,6 @@ class BaseTest < Test::Unit::TestCase assert_equal 'addresses', StreetAddress.collection_name end - def test_nested_element_name - self.class.const_set :Actor, Class.new(Person) - assert_equal 'base_test/actor', Actor.element_name - ensure - self.class.remove_const :Actor rescue nil - end - - def test_prefix assert_equal "/", Person.prefix assert_equal Set.new, Person.send(:prefix_parameters) @@ -215,7 +207,7 @@ class BaseTest < Test::Unit::TestCase end def test_create_with_custom_prefix - matzs_house = StreetAddress.new({}, {:person_id => 1}) + matzs_house = StreetAddress.new({}, { :person_id => 1 }) matzs_house.save assert_equal '5', matzs_house.id end @@ -232,6 +224,9 @@ class BaseTest < Test::Unit::TestCase assert rick.valid? assert !rick.new? assert_equal '5', rick.id + + # test additional attribute returned on create + assert_equal 25, rick.age # Test that save exceptions get bubbled up too ActiveResource::HttpMock.respond_to do |mock| diff --git a/activeresource/test/connection_test.rb b/activeresource/test/connection_test.rb index 8fcbf089de..b434dd4012 100644 --- a/activeresource/test/connection_test.rb +++ b/activeresource/test/connection_test.rb @@ -92,7 +92,7 @@ class ConnectionTest < Test::Unit::TestCase def test_get_collection_empty people = @conn.get("/people_empty_elements.xml") - assert_equal people, nil + assert_nil people end def test_post -- cgit v1.2.3