From 470fc0209699d70e9e2349d35f3210757a7a7d17 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 21 Dec 2007 21:42:27 +0000 Subject: Document custom methods. Closes #10589. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@8472 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activeresource/CHANGELOG | 2 + activeresource/lib/active_resource/base.rb | 46 +++++++---- .../lib/active_resource/custom_methods.rb | 96 +++++++++++++--------- 3 files changed, 87 insertions(+), 57 deletions(-) diff --git a/activeresource/CHANGELOG b/activeresource/CHANGELOG index f2a8472649..69b387d9b9 100644 --- a/activeresource/CHANGELOG +++ b/activeresource/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Document custom methods. #10589 [Cheah Chu Yeow] + * Ruby 1.9 compatibility. [Jeremy Kemper] diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb index 47c4d0c8f1..3383f542f9 100644 --- a/activeresource/lib/active_resource/base.rb +++ b/activeresource/lib/active_resource/base.rb @@ -5,7 +5,7 @@ require 'set' 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 get, + # post, post and put 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,12 +98,12 @@ 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 404 (Resource Not Found) # response code will be returned from the server which will raise an ActiveResource::ResourceNotFound # exception. # @@ -100,7 +111,7 @@ module ActiveResource # 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 + # 404 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 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. # # ryan = Person.find(1) # ryan.first #=> '' @@ -191,7 +202,7 @@ module ActiveResource # 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 false). def connection(refresh = false) if defined?(@connection) || superclass == Object @connection = Connection.new(site, format) if refresh || @connection.nil? @@ -372,6 +383,9 @@ module ActiveResource # 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 @@ module ActiveResource # # 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 false). # 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 false). # # ==== Examples # my_group = SubsidiaryGroup.find(:first) @@ -769,8 +783,8 @@ module ActiveResource 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 true to my_person.respond_to?("name"), my_person.respond_to?("name="), and + # my_person.respond_to?("name?"). def respond_to?(method, include_priv = false) method_name = method.to_s if attributes.nil? diff --git a/activeresource/lib/active_resource/custom_methods.rb b/activeresource/lib/active_resource/custom_methods.rb index e08c664307..4f5697fcf1 100644 --- a/activeresource/lib/active_resource/custom_methods.rb +++ b/activeresource/lib/active_resource/custom_methods.rb @@ -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 find class method with the + # :from 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) -- cgit v1.2.3