Permalink
Browse files

Document custom methods. Closes #10589.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@8472 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
1 parent a3bfb66 commit 470fc0209699d70e9e2349d35f3210757a7a7d17 @jeremy jeremy committed Dec 21, 2007
@@ -1,5 +1,7 @@
*SVN*
+* Document custom methods. #10589 [Cheah Chu Yeow]
+
* Ruby 1.9 compatibility. [Jeremy Kemper]
@@ -5,7 +5,7 @@
module ActiveResource
# ActiveResource::Base is the main class for mapping RESTful resources as models in a Rails application.
#
- # For an outline of what Active Resource is capable of, see link:files/README.html.
+ # For an outline of what Active Resource is capable of, see link:files/vendor/rails/activeresource/README.html.
#
# == Automated mapping
#
@@ -33,7 +33,7 @@ module ActiveResource
# ryan.exists? #=> true
#
# ryan = Person.find(1)
- # # => Resource holding our newly create Person object
+ # # => Resource holding our newly created Person object
#
# ryan.first = 'Rizzle'
# ryan.save #=> true
@@ -46,15 +46,26 @@ module ActiveResource
# === Custom REST methods
#
# Since simple CRUD/lifecycle methods can't accomplish every task, Active Resource also supports
- # defining your own custom REST methods.
- #
- # Person.new(:name => 'Ryan).post(:register)
+ # defining your own custom REST methods. To invoke them, Active Resource provides the <tt>get</tt>,
+ # <tt>post</tt>, <tt>post</tt> and <tt>put</tt> methods where you can specify a custom REST method
+ # name to invoke.
+ #
+ # # POST to the custom 'register' REST method, i.e. POST /people/new/register.xml.
+ # Person.new(:name => 'Ryan').post(:register)
# # => { :id => 1, :name => 'Ryan', :position => 'Clerk' }
#
+ # # PUT an update by invoking the 'promote' REST method, i.e. PUT /people/1/promote.xml?position=Manager.
# Person.find(1).put(:promote, :position => 'Manager')
# # => { :id => 1, :name => 'Ryan', :position => 'Manager' }
+ #
+ # # GET all the positions available, i.e. GET /people/positions.xml.
+ # Person.get(:positions)
+ # # => [{:name => 'Manager'}, {:name => 'Clerk'}]
+ #
+ # # DELETE to 'fire' a person, i.e. DELETE /people/1/fire.xml.
+ # Person.find(1).delete(:fire)
#
- # For more information on creating and using custom REST methods, see the
+ # For more information on using custom REST methods, see the
# ActiveResource::CustomMethods documentation.
#
# == Validations
@@ -87,20 +98,20 @@ module ActiveResource
# == Errors & Validation
#
# Error handling and validation is handled in much the same manner as you're used to seeing in
- # Active Record. Both the response code in the Http response and the body of the response are used to
+ # Active Record. Both the response code in the HTTP response and the body of the response are used to
# indicate that an error occurred.
#
# === Resource errors
#
- # When a get is requested for a resource that does not exist, the HTTP +404+ (Resource Not Found)
+ # When a GET is requested for a resource that does not exist, the HTTP <tt>404</tt> (Resource Not Found)
# response code will be returned from the server which will raise an ActiveResource::ResourceNotFound
# exception.
#
# # GET http://api.people.com:3000/people/999.xml
# ryan = Person.find(999) # => Raises ActiveResource::ResourceNotFound
# # => Response = 404
#
- # +404+ is just one of the HTTP error response codes that ActiveResource will handle with its own exception. The
+ # <tt>404</tt> is just one of the HTTP error response codes that ActiveResource will handle with its own exception. The
# following HTTP response codes will also result in these exceptions:
#
# 200 - 399:: Valid response, no exception
@@ -125,8 +136,8 @@ module ActiveResource
#
# Active Resource supports validations on resources and will return errors if any these validations fail
# (e.g., "First name can not be blank" and so on). These types of errors are denoted in the response by
- # a response code of +422+ and an XML representation of the validation errors. The save operation will
- # then fail (with a +false+ return value) and the validation errors can be accessed on the resource in question.
+ # a response code of <tt>422</tt> and an XML representation of the validation errors. The save operation will
+ # then fail (with a <tt>false</tt> return value) and the validation errors can be accessed on the resource in question.
#
# ryan = Person.find(1)
# ryan.first #=> ''
@@ -191,7 +202,7 @@ def format # :nodoc:
# An instance of ActiveResource::Connection that is the base connection to the remote service.
# The +refresh+ parameter toggles whether or not the connection is refreshed at every request
- # or not (defaults to +false+).
+ # or not (defaults to <tt>false</tt>).
def connection(refresh = false)
if defined?(@connection) || superclass == Object
@connection = Connection.new(site, format) if refresh || @connection.nil?
@@ -372,6 +383,9 @@ def create(attributes = {})
# Person.find(:one, :from => :leader)
# # => GET /people/leader.xml
#
+ # Person.find(:all, :from => :developers, :params => { :language => 'ruby' })
+ # # => GET /people/developers.xml?language=ruby
+ #
# Person.find(:one, :from => "/companies/1/manager.xml")
# # => GET /companies/1/manager.xml
#
@@ -687,9 +701,9 @@ def exists?
#
# indent:: Set the indent level for the XML output (default is +2+).
# dasherize:: Boolean option to determine whether or not element names should
- # replace underscores with dashes (default is +false+).
+ # replace underscores with dashes (default is <tt>false</tt>).
# skip_instruct:: Toggle skipping the +instruct!+ call on the XML builder
- # that generates the XML declaration (default is +false+).
+ # that generates the XML declaration (default is <tt>false</tt>).
#
# ==== Examples
# my_group = SubsidiaryGroup.find(:first)
@@ -769,8 +783,8 @@ def load(attributes)
alias_method :respond_to_without_attributes?, :respond_to?
# A method to determine if an object responds to a message (e.g., a method call). In Active Resource, a +Person+ object with a
- # +name+ attribute can answer +true+ to +my_person.respond_to?("name")+, +my_person.respond_to?("name=")+, and
- # +my_person.respond_to?("name?")+.
+ # +name+ attribute can answer <tt>true</tt> to <tt>my_person.respond_to?("name")</tt>, <tt>my_person.respond_to?("name=")</tt>, and
+ # <tt>my_person.respond_to?("name?")</tt>.
def respond_to?(method, include_priv = false)
method_name = method.to_s
if attributes.nil?
@@ -1,59 +1,73 @@
-# 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 },
-# :element => { :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'}]
-#
module ActiveResource
+ # 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 },
+ # :element => { :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'}]
+ #
module CustomMethods
- def self.included(within)
- within.class_eval do
+ def self.included(base)
+ base.class_eval do
extend ActiveResource::CustomMethods::ClassMethods
include ActiveResource::CustomMethods::InstanceMethods
class << self
alias :orig_delete :delete
- def get(method_name, options = {})
- connection.get(custom_method_collection_url(method_name, options), headers)
+ # 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 instances - they are ordinary Hashes. If you are expecting
+ # ActiveResource 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(method_name, options = {}, body = '')
- connection.post(custom_method_collection_url(method_name, options), body, headers)
+ def post(custom_method_name, options = {}, body = '')
+ connection.post(custom_method_collection_url(custom_method_name, options), body, headers)
end
- def put(method_name, options = {}, body = '')
- connection.put(custom_method_collection_url(method_name, options), body, headers)
+ def put(custom_method_name, options = {}, body = '')
+ connection.put(custom_method_collection_url(custom_method_name, options), body, headers)
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))
+ # 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)

0 comments on commit 470fc02

Please sign in to comment.