From c918fbf14b96319412cb6195e7a8a3229613340c Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 4 Sep 2006 10:04:23 +0000 Subject: Deep hashes are converted into collections of resources. Class attribute writer methods. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4985 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activeresource/lib/active_resource/base.rb | 60 +++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 9 deletions(-) (limited to 'activeresource/lib') diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb index f722be4162..ec6cee19fa 100644 --- a/activeresource/lib/active_resource/base.rb +++ b/activeresource/lib/active_resource/base.rb @@ -7,6 +7,8 @@ module ActiveResource def site=(site) @site = site.is_a?(URI) ? site : URI.parse(site) + @connection = nil + @site end def connection(refresh = false) @@ -25,25 +27,28 @@ module ActiveResource def prefix(options={}) default = site.path default << '/' unless default[-1..-1] == '/' - set_prefix default + self.prefix = default prefix(options) end - def set_prefix(value = '/') + def prefix=(value = '/') prefix_call = value.gsub(/:\w+/) { |s| "\#{options[#{s}]}" } method_decl = %(def self.prefix(options={}) "#{prefix_call}" end) eval method_decl end + alias_method :set_prefix, :prefix= - def set_element_name(value) + def element_name=(value) class << self ; attr_reader :element_name ; end @element_name = value end + alias_method :set_element_name, :element_name= - def set_collection_name(value) + def collection_name=(value) class << self ; attr_reader :collection_name ; end @collection_name = value end + alias_method :set_collection_name, :collection_name= def element_path(id, options = {}) "#{prefix(options)}#{collection_name}/#{id}.xml" @@ -54,13 +59,14 @@ module ActiveResource end def primary_key - set_primary_key 'id' + self.primary_key = 'id' end - def set_primary_key(value) + def primary_key=(value) class << self ; attr_reader :primary_key ; end @primary_key = value end + alias_method :set_primary_key, :primary_key= # Person.find(1) # => GET /people/1.xml # StreetAddress.find(1, :person_id => 1) # => GET /people/1/street_addresses/1.xml @@ -91,7 +97,8 @@ module ActiveResource attr_accessor :prefix_options def initialize(attributes = {}, prefix_options = {}) - @attributes = attributes + @attributes = {} + self.load attributes @prefix_options = prefix_options end @@ -114,14 +121,34 @@ module ActiveResource def destroy 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.load self.class.find(id, @prefix_options).attributes + end + + # Manually load attributes from a hash. Recursively loads collections of + # resources. + def load(attributes) + attributes.each do |key, value| + @attributes[key.to_s] = + case value + when Array + resource = find_or_create_resource_for_collection(key) + value.map { |attrs| resource.new(attrs) } + when Hash + resource = find_or_create_resource_for(key) + resource.new(value) + when ActiveResource::Base + value.class.new(value.attributes) + else + value.dup rescue value + end + end self end @@ -140,6 +167,21 @@ module ActiveResource end end + private + def find_or_create_resource_for_collection(name) + find_or_create_resource_for(name.to_s.singularize) + end + + def find_or_create_resource_for(name) + resource_name = name.to_s.camelize + resource_name.constantize + rescue NameError + resource = self.class.const_set(resource_name, Class.new(ActiveResource::Base)) + resource.prefix = self.class.prefix + resource.site = self.class.site + resource + end + def method_missing(method_symbol, *arguments) method_name = method_symbol.to_s -- cgit v1.2.3