aboutsummaryrefslogtreecommitdiffstats
path: root/activeresource/lib/active_resource
diff options
context:
space:
mode:
Diffstat (limited to 'activeresource/lib/active_resource')
-rw-r--r--activeresource/lib/active_resource/base.rb117
-rw-r--r--activeresource/lib/active_resource/connection.rb11
2 files changed, 95 insertions, 33 deletions
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