Module: ActiveResource::CustomMethods

Defined in:
lib/active_resource/custom_methods.rb

Overview

A module to support custom REST methods and sub-resources, allowing you to break out of the “default” REST methods with your own custom resource requests. For example, say you use Rails to expose a REST service and configure your routes with:

  map.resources :people, :new => { :register => :post },
                         :member => { :promote => :put, :deactivate => :delete }
                         :collection => { :active => :get }

This route set 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

Using this module, Active Resource can use these custom REST methods just like the standard methods.

class Person < ActiveResource::Base
  self.site = "http://37s.sunrise.i:3000"
end

Person.new(:name => 'Ryan).post(:register)  # POST /people/new/register.xml
# => { :id => 1, :name => 'Ryan' }

Person.find(1).put(:promote, :position => 'Manager') # PUT /people/1/promote.xml
Person.find(1).delete(:deactivate) # DELETE /people/1/deactivate.xml

Person.get(:active)  # GET /people/active.xml
# => [{:id => 1, :name => 'Ryan'}, {:id => 2, :name => 'Joe'}]

Defined Under Namespace

Modules: ClassMethods, InstanceMethods

Class Method Summary collapse

Class Method Details

.included(base) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/active_resource/custom_methods.rb', line 34

def self.included(base)
  base.class_eval do
    extend ActiveResource::CustomMethods::ClassMethods
    include ActiveResource::CustomMethods::InstanceMethods

    class << self
      alias :orig_delete :delete

      # Invokes a GET to a given custom REST method. For example:
      #
      #   Person.get(:active)  # GET /people/active.xml
      #   # => [{:id => 1, :name => 'Ryan'}, {:id => 2, :name => 'Joe'}]
      #
      #   Person.get(:active, :awesome => true)  # GET /people/active.xml?awesome=true
      #   # => [{:id => 1, :name => 'Ryan'}]
      #
      # Note: the objects returned from this method are not automatically converted
      # into ActiveResource::Base instances - they are ordinary Hashes. If you are expecting
      # ActiveResource::Base instances, use the <tt>find</tt> class method with the
      # <tt>:from</tt> option. For example:
      #
      #   Person.find(:all, :from => :active)
      def get(custom_method_name, options = {})
        connection.get(custom_method_collection_url(custom_method_name, options), headers)
      end

      def post(custom_method_name, options = {}, body = '')
        connection.post(custom_method_collection_url(custom_method_name, options), body, headers)
      end

      def put(custom_method_name, options = {}, body = '')
        connection.put(custom_method_collection_url(custom_method_name, options), body, headers)
      end

      def delete(custom_method_name, options = {})
        # Need to jump through some hoops to retain the original class 'delete' method
        if custom_method_name.is_a?(Symbol)
          connection.delete(custom_method_collection_url(custom_method_name, options), headers)
        else
          orig_delete(custom_method_name, options)
        end
      end
    end
  end
end