From 7749c9c2200ad190e3f9935c27f09ec9b95227f2 Mon Sep 17 00:00:00 2001 From: Rick Olson Date: Fri, 1 Sep 2006 01:15:10 +0000 Subject: Major updates to ActiveResource, please see changelog and unit tests [Rick Olson] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4890 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activeresource/lib/active_resource/base.rb | 117 +++++++++++++++++------ activeresource/lib/active_resource/connection.rb | 11 ++- 2 files changed, 95 insertions(+), 33 deletions(-) (limited to 'activeresource/lib') diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb index 11064454d7..f722be4162 100644 --- a/activeresource/lib/active_resource/base.rb +++ b/activeresource/lib/active_resource/base.rb @@ -3,12 +3,10 @@ require 'active_resource/connection' module ActiveResource class Base class << self - def site=(site) - @@site = site.is_a?(URI) ? site : URI.parse(site) - end + attr_reader :site - def site - @@site + def site=(site) + @site = site.is_a?(URI) ? site : URI.parse(site) end def connection(refresh = false) @@ -23,66 +21,125 @@ module ActiveResource def collection_name element_name.pluralize end + + def prefix(options={}) + default = site.path + default << '/' unless default[-1..-1] == '/' + set_prefix default + prefix(options) + end + + def set_prefix(value = '/') + prefix_call = value.gsub(/:\w+/) { |s| "\#{options[#{s}]}" } + method_decl = %(def self.prefix(options={}) "#{prefix_call}" end) + eval method_decl + end + + def set_element_name(value) + class << self ; attr_reader :element_name ; end + @element_name = value + end + + def set_collection_name(value) + class << self ; attr_reader :collection_name ; end + @collection_name = value + end + + def element_path(id, options = {}) + "#{prefix(options)}#{collection_name}/#{id}.xml" + end + + def collection_path(options = {}) + "#{prefix(options)}#{collection_name}.xml" + end - def element_path(id) - "/#{collection_name}/#{id}.xml" + def primary_key + set_primary_key 'id' end - def collection_path - "/#{collection_name}.xml" + def set_primary_key(value) + class << self ; attr_reader :primary_key ; end + @primary_key = value end + # Person.find(1) # => GET /people/1.xml + # StreetAddress.find(1, :person_id => 1) # => GET /people/1/street_addresses/1.xml def find(*arguments) - scope = arguments.slice!(0) + scope = arguments.slice!(0) + options = arguments.slice!(0) || {} case scope - when Fixnum - # { :person => person1 } - new(connection.get(element_path(scope)).values.first) - when :all - # { :people => { :person => [ person1, person2 ] } } - connection.get(collection_path).values.first.values.first.collect { |element| new(element) } - when :first - find(:all, *arguments).first + when :all then find_every(options) + when :first then find_every(options).first + else find_single(scope, options) end end + + private + # { :people => { :person => [ person1, person2 ] } } + def find_every(options) + connection.get(collection_path(options)).values.first.values.first.collect { |element| new(element, options) } + end + + # { :person => person1 } + def find_single(scope, options) + new(connection.get(element_path(scope, options)).values.first, options) + end end attr_accessor :attributes + attr_accessor :prefix_options - def initialize(attributes = {}) - @attributes = attributes + def initialize(attributes = {}, prefix_options = {}) + @attributes = attributes + @prefix_options = prefix_options end - + + def new_resource? + id.nil? + end + def id - attributes["id"] + attributes[self.class.primary_key] end def id=(id) - attributes["id"] = id + attributes[self.class.primary_key] = id end def save - update + new_resource? ? create : update end def destroy - connection.delete(self.class.element_path(id)) + connection.delete(self.class.element_path(id, prefix_options)[0..-5]) end def to_xml attributes.to_xml(:root => self.class.element_name) end - + + # Reloads the attributes of this object from the remote web service. + def reload + @attributes.update(self.class.find(self.id, @prefix_options).instance_variable_get(:@attributes)) + self + end + protected def connection(refresh = false) self.class.connection(refresh) end def update - connection.put(self.class.element_path(id), to_xml) + connection.put(self.class.element_path(id, prefix_options)[0..-5], to_xml) end - + + def create + returning connection.post(self.class.collection_path(prefix_options)[0..-5], to_xml) do |resp| + self.id = resp['Location'][/\/([^\/]*?)(\.\w+)?$/, 1] + end + end + def method_missing(method_symbol, *arguments) method_name = method_symbol.to_s @@ -90,9 +147,9 @@ module ActiveResource when "=" attributes[method_name.first(-1)] = arguments.first when "?" - # TODO + attributes[method_name.first(-1)] == true else - attributes[method_name] || super + attributes.has_key?(method_name) ? attributes[method_name] : super end end end diff --git a/activeresource/lib/active_resource/connection.rb b/activeresource/lib/active_resource/connection.rb index cc98645fdc..22689444b2 100644 --- a/activeresource/lib/active_resource/connection.rb +++ b/activeresource/lib/active_resource/connection.rb @@ -33,6 +33,11 @@ module ActiveResource def requests @@requests ||= [] end + + def default_header + class << self ; attr_reader :default_header end + @default_header = { 'Content-Type' => 'application/xml' } + end end def initialize(site) @@ -44,15 +49,15 @@ module ActiveResource end def delete(path) - request(:delete, path) + request(:delete, path, self.class.default_header) end def put(path, body = '') - request(:put, path, body) + request(:put, path, body, self.class.default_header) end def post(path, body = '') - request(:post, path, body) + request(:post, path, body, self.class.default_header) end private -- cgit v1.2.3