diff options
author | David Heinemeier Hansson <david@loudthinking.com> | 2007-09-20 23:18:05 +0000 |
---|---|---|
committer | David Heinemeier Hansson <david@loudthinking.com> | 2007-09-20 23:18:05 +0000 |
commit | dc399b96c84bc66b7c20e92fb40e9ed00daf99c2 (patch) | |
tree | 57edd3b3d5cf446392aaecfebc5a1831e960e4c8 /activeresource/lib | |
parent | bd311ce9221f1df9711c791d9abfae89e029924d (diff) | |
download | rails-dc399b96c84bc66b7c20e92fb40e9ed00daf99c2.tar.gz rails-dc399b96c84bc66b7c20e92fb40e9ed00daf99c2.tar.bz2 rails-dc399b96c84bc66b7c20e92fb40e9ed00daf99c2.zip |
Added ActiveResource.format= which defaults to :xml but can also be set to :json [DHH]. Added one-off declarations of mock behavior [DHH]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7518 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activeresource/lib')
-rw-r--r-- | activeresource/lib/active_resource.rb | 1 | ||||
-rw-r--r-- | activeresource/lib/active_resource/base.rb | 34 | ||||
-rw-r--r-- | activeresource/lib/active_resource/connection.rb | 30 | ||||
-rw-r--r-- | activeresource/lib/active_resource/formats.rb | 14 | ||||
-rw-r--r-- | activeresource/lib/active_resource/formats/json_format.rb | 23 | ||||
-rw-r--r-- | activeresource/lib/active_resource/formats/xml_format.rb | 34 | ||||
-rw-r--r-- | activeresource/lib/active_resource/http_mock.rb | 7 |
7 files changed, 115 insertions, 28 deletions
diff --git a/activeresource/lib/active_resource.rb b/activeresource/lib/active_resource.rb index 67961630e3..96f2257a04 100644 --- a/activeresource/lib/active_resource.rb +++ b/activeresource/lib/active_resource.rb @@ -34,6 +34,7 @@ unless defined?(ActiveSupport) end end +require 'active_resource/formats' require 'active_resource/base' require 'active_resource/validations' require 'active_resource/custom_methods' diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb index d33195e261..d99a047df1 100644 --- a/activeresource/lib/active_resource/base.rb +++ b/activeresource/lib/active_resource/base.rb @@ -155,7 +155,7 @@ module ActiveResource def site if defined?(@site) @site - elsif superclass != Object and superclass.site + elsif superclass != Object && superclass.site superclass.site.dup.freeze end end @@ -167,12 +167,34 @@ module ActiveResource @site = site.nil? ? nil : create_site_uri_from(site) end + # Sets the format that attributes are sent and received in from a mime type reference. Example: + # + # Person.format = :json + # Person.find(1) # => GET /people/1.json + # + # Person.format = ActiveResource::Formats::XmlFormat + # Person.find(1) # => GET /people/1.xml + # + # Default format is :xml. + def format=(mime_type_reference_or_format) + format = mime_type_reference_or_format.is_a?(Symbol) ? + ActiveResource::Formats[mime_type_reference_or_format] : mime_type_reference_or_format + + write_inheritable_attribute("format", format) + connection.format = format + end + + # Returns the current format, default is ActiveResource::Formats::XmlFormat + def format # :nodoc: + read_inheritable_attribute("format") || ActiveResource::Formats[:xml] + end + # An instance of ActiveResource::Connection that is the base connection to the remote service. # The +refresh+ parameter toggles whether or not the connection is refreshed at every request # or not (defaults to +false+). def connection(refresh = false) - if defined?(@connection) or superclass == Object - @connection = Connection.new(site) if refresh || @connection.nil? + if defined?(@connection) || superclass == Object + @connection = Connection.new(site, format) if refresh || @connection.nil? @connection else superclass.connection @@ -252,7 +274,7 @@ module ActiveResource # def element_path(id, prefix_options = {}, query_options = nil) prefix_options, query_options = split_options(prefix_options) if query_options.nil? - "#{prefix(prefix_options)}#{collection_name}/#{id}.xml#{query_string(query_options)}" + "#{prefix(prefix_options)}#{collection_name}/#{id}.#{format.extension}#{query_string(query_options)}" end # Gets the collection path for the REST resources. If the +query_options+ parameter is omitted, Rails @@ -278,7 +300,7 @@ module ActiveResource # def collection_path(prefix_options = {}, query_options = nil) prefix_options, query_options = split_options(prefix_options) if query_options.nil? - "#{prefix(prefix_options)}#{collection_name}.xml#{query_string(query_options)}" + "#{prefix(prefix_options)}#{collection_name}.#{format.extension}#{query_string(query_options)}" end alias_method :set_primary_key, :primary_key= #:nodoc: @@ -781,7 +803,7 @@ module ActiveResource def load_attributes_from_response(response) if response['Content-size'] != "0" && response.body.strip.size > 0 - load(connection.xml_from_response(response)) + load(self.class.format.decode(response.body)) end end diff --git a/activeresource/lib/active_resource/connection.rb b/activeresource/lib/active_resource/connection.rb index 07f3c98eda..5f86d77a26 100644 --- a/activeresource/lib/active_resource/connection.rb +++ b/activeresource/lib/active_resource/connection.rb @@ -47,23 +47,20 @@ module ActiveResource # services. class Connection attr_reader :site + attr_accessor :format class << self def requests @@requests ||= [] end - - def default_header - class << self ; attr_reader :default_header end - @default_header = { 'Content-Type' => 'application/xml' } - end end # The +site+ parameter is required and will set the +site+ # attribute to the URI for the remote resource service. - def initialize(site) + def initialize(site, format = ActiveResource::Formats[:xml]) raise ArgumentError, 'Missing site URI' unless site self.site = site + self.format = format end # Set URI for remote service. @@ -74,7 +71,7 @@ module ActiveResource # Execute a GET request. # Used to get (find) resources. def get(path, headers = {}) - xml_from_response(request(:get, path, build_request_headers(headers))) + format.decode(request(:get, path, build_request_headers(headers)).body) end # Execute a DELETE request (see HTTP protocol documentation if unfamiliar). @@ -95,9 +92,6 @@ module ActiveResource request(:post, path, body.to_s, build_request_headers(headers)) end - def xml_from_response(response) - from_xml_data(Hash.from_xml(response.body)) - end private # Makes request to remote service. @@ -144,10 +138,14 @@ module ActiveResource @http end + + def default_header + @default_header ||= { 'Content-Type' => format.mime_type } + end # Builds headers for request to remote service. def build_request_headers(headers) - authorization_header.update(self.class.default_header).update(headers) + authorization_header.update(default_header).update(headers) end # Sets authorization header; authentication information is pulled from credentials provided with site URI. @@ -158,15 +156,5 @@ module ActiveResource def logger #:nodoc: ActiveResource::Base.logger end - - # Manipulate from_xml Hash, because xml_simple is not exactly what we - # want for ActiveResource. - def from_xml_data(data) - if data.is_a?(Hash) && data.keys.size == 1 - data.values.first - else - data - end - end end end
\ No newline at end of file diff --git a/activeresource/lib/active_resource/formats.rb b/activeresource/lib/active_resource/formats.rb new file mode 100644 index 0000000000..28864cf588 --- /dev/null +++ b/activeresource/lib/active_resource/formats.rb @@ -0,0 +1,14 @@ +module ActiveResource + module Formats + # Lookup the format class from a mime type reference symbol. Example: + # + # ActiveResource::Formats[:xml] # => ActiveResource::Formats::XmlFormat + # ActiveResource::Formats[:json] # => ActiveResource::Formats::JsonFormat + def self.[](mime_type_reference) + ActiveResource::Formats.const_get(mime_type_reference.to_s.camelize + "Format") + end + end +end + +require 'active_resource/formats/xml_format' +require 'active_resource/formats/json_format'
\ No newline at end of file diff --git a/activeresource/lib/active_resource/formats/json_format.rb b/activeresource/lib/active_resource/formats/json_format.rb new file mode 100644 index 0000000000..df0d6ca372 --- /dev/null +++ b/activeresource/lib/active_resource/formats/json_format.rb @@ -0,0 +1,23 @@ +module ActiveResource + module Formats + module JsonFormat + extend self + + def extension + "json" + end + + def mime_type + "application/json" + end + + def encode(hash) + hash.to_json + end + + def decode(json) + ActiveSupport::JSON.decode(json) + end + end + end +end
\ No newline at end of file diff --git a/activeresource/lib/active_resource/formats/xml_format.rb b/activeresource/lib/active_resource/formats/xml_format.rb new file mode 100644 index 0000000000..01c28dcee6 --- /dev/null +++ b/activeresource/lib/active_resource/formats/xml_format.rb @@ -0,0 +1,34 @@ +module ActiveResource + module Formats + module XmlFormat + extend self + + def extension + "xml" + end + + def mime_type + "application/xml" + end + + def encode(hash) + hash.to_xml + end + + def decode(xml) + from_xml_data(Hash.from_xml(xml)) + end + + private + # Manipulate from_xml Hash, because xml_simple is not exactly what we + # want for ActiveResource. + def from_xml_data(data) + if data.is_a?(Hash) && data.keys.size == 1 + data.values.first + else + data + end + end + end + end +end
\ No newline at end of file diff --git a/activeresource/lib/active_resource/http_mock.rb b/activeresource/lib/active_resource/http_mock.rb index 16ac62bf13..c9a2c21f31 100644 --- a/activeresource/lib/active_resource/http_mock.rb +++ b/activeresource/lib/active_resource/http_mock.rb @@ -32,7 +32,12 @@ module ActiveResource pairs.each do |(path, response)| responses[path] = response end - yield Responder.new(responses) if block_given? + + if block_given? + yield Responder.new(responses) + else + Responder.new(responses) + end end def reset! |