aboutsummaryrefslogtreecommitdiffstats
path: root/activeresource/lib
diff options
context:
space:
mode:
Diffstat (limited to 'activeresource/lib')
-rw-r--r--activeresource/lib/active_resource.rb2
-rw-r--r--activeresource/lib/active_resource/base.rb1
-rw-r--r--activeresource/lib/active_resource/custom_methods.rb104
-rw-r--r--activeresource/lib/active_resource/http_mock.rb8
4 files changed, 115 insertions, 0 deletions
diff --git a/activeresource/lib/active_resource.rb b/activeresource/lib/active_resource.rb
index a1af676086..83039606af 100644
--- a/activeresource/lib/active_resource.rb
+++ b/activeresource/lib/active_resource.rb
@@ -37,9 +37,11 @@ end
require 'active_resource/base'
require 'active_resource/struct'
require 'active_resource/validations'
+require 'active_resource/custom_methods'
module ActiveResource
Base.class_eval do
include Validations
+ include CustomMethods
end
end \ No newline at end of file
diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
index cd1f07e294..6fa301d740 100644
--- a/activeresource/lib/active_resource/base.rb
+++ b/activeresource/lib/active_resource/base.rb
@@ -122,6 +122,7 @@ module ActiveResource
case scope
when :all then find_every(options)
when :first then find_every(options).first
+ when Symbol then get(scope, options)
else find_single(scope, options)
end
end
diff --git a/activeresource/lib/active_resource/custom_methods.rb b/activeresource/lib/active_resource/custom_methods.rb
new file mode 100644
index 0000000000..de99305b93
--- /dev/null
+++ b/activeresource/lib/active_resource/custom_methods.rb
@@ -0,0 +1,104 @@
+# Support custom methods and sub-resources for REST.
+#
+# Say you on the server configure your routes with:
+#
+# map.resources :people, :new => { :register => :post },
+# :element => { :promote => :put, :deactivate => :delete }
+# :collection => { :active => :get }
+#
+# Which creates routes for the following http requests:
+#
+# POST /people/new/register.xml #=> PeopleController.register
+# PUT /people/1/promote.xml #=> PeopleController.promote with :id => 1
+# DELETE /people/1/deactivate.xml #=> PeopleController.deactivate with :id => 1
+# GET /people/active.xml #=> PeopleController.active
+#
+# This module provides the ability for Active Resource to call these
+# custom REST methods and get the response back.
+#
+# class Person < ActiveResource::Base
+# self.site = "http://37s.sunrise.i:3000"
+# end
+#
+# Person.new(:name => 'Ryan).post(:register) #=> { :id => 1, :name => 'Ryan' }
+#
+# Person.find(1).put(:promote, :position => 'Manager')
+# Person.find(1).delete(:deactivate)
+#
+# Person.get(:active) #=> [{:id => 1, :name => 'Ryan'}, {:id => 2, :name => 'Joe'}]
+module ActiveResource
+ module CustomMethods
+ def self.included(within)
+ within.class_eval do
+ class << self
+ include ActiveResource::CustomMethods::ClassMethods
+
+ alias :orig_delete :delete
+
+ def get(method_name, options = {})
+ connection.get(custom_method_collection_url(method_name, options))
+ end
+
+ def post(method_name, options = {}, body = nil)
+ connection.post(custom_method_collection_url(method_name, options), body)
+ end
+
+ def put(method_name, options = {}, body = nil)
+ connection.put(custom_method_collection_url(method_name, options), body)
+ end
+
+ # Need to jump through some hoops to retain the original class 'delete' method
+ def delete(custom_method_name, options = {})
+ if (custom_method_name.is_a?(Symbol))
+ connection.delete(custom_method_collection_url(custom_method_name, options))
+ else
+ orig_delete(custom_method_name, options)
+ end
+ end
+ end
+
+ end
+
+ within.send(:include, ActiveResource::CustomMethods::InstanceMethods)
+ end
+
+ module ClassMethods
+ def custom_method_collection_url(method_name, options = {})
+ prefix_options, query_options = split_options(options)
+ "#{prefix(prefix_options)}#{collection_name}/#{method_name}.xml#{query_string(query_options)}"
+ end
+ end
+
+ module InstanceMethods
+ def get(method_name, options = {})
+ connection.get(custom_method_element_url(method_name, options))
+ end
+
+ def post(method_name, options = {}, body = nil)
+ if new?
+ connection.post(custom_method_new_element_url(method_name, options), (body.nil? ? to_xml : body))
+ else
+ connection.post(custom_method_element_url(method_name, options), body)
+ end
+ end
+
+ def put(method_name, options = {}, body = nil)
+ connection.put(custom_method_element_url(method_name, options), body)
+ end
+
+ def delete(method_name, options = {})
+ connection.delete(custom_method_element_url(method_name, options))
+ end
+
+
+ private
+ def custom_method_element_url(method_name, options = {})
+ "#{self.class.prefix(prefix_options)}#{self.class.collection_name}/#{id}/#{method_name}.xml#{self.class.send(:query_string, options)}"
+ end
+
+ def custom_method_new_element_url(method_name, options = {})
+ "#{self.class.prefix(prefix_options)}#{self.class.collection_name}/new/#{method_name}.xml#{self.class.send(:query_string, options)}"
+ 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 90823babd1..16ac62bf13 100644
--- a/activeresource/lib/active_resource/http_mock.rb
+++ b/activeresource/lib/active_resource/http_mock.rb
@@ -110,6 +110,14 @@ module ActiveResource
def []=(key, value)
headers[key] = value
end
+
+ def ==(other)
+ if (other.is_a?(Response))
+ other.body == body && other.message == message && other.headers == headers
+ else
+ false
+ end
+ end
end
class Connection