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.rb157
-rw-r--r--activeresource/lib/active_resource/connection.rb53
-rw-r--r--activeresource/lib/active_resource/custom_methods.rb54
-rw-r--r--activeresource/lib/active_resource/exceptions.rb32
-rw-r--r--activeresource/lib/active_resource/http_mock.rb21
-rw-r--r--activeresource/lib/active_resource/validations.rb2
-rw-r--r--activeresource/lib/active_resource/version.rb4
7 files changed, 175 insertions, 148 deletions
diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
index 1ffd83b91d..c0d51797ee 100644
--- a/activeresource/lib/active_resource/base.rb
+++ b/activeresource/lib/active_resource/base.rb
@@ -25,29 +25,29 @@ module ActiveResource
#
# == Automated mapping
#
- # Active Resource objects represent your RESTful resources as manipulatable Ruby objects. To map resources
+ # Active Resource objects represent your RESTful resources as manipulatable Ruby objects. To map resources
# to Ruby objects, Active Resource only needs a class name that corresponds to the resource name (e.g., the class
# Person maps to the resources people, very similarly to Active Record) and a +site+ value, which holds the
# URI of the resources.
#
# class Person < ActiveResource::Base
- # self.site = "http://api.people.com:3000/"
+ # self.site = "https://api.people.com"
# end
#
- # Now the Person class is mapped to RESTful resources located at <tt>http://api.people.com:3000/people/</tt>, and
+ # Now the Person class is mapped to RESTful resources located at <tt>https://api.people.com/people/</tt>, and
# you can now use Active Resource's life cycle methods to manipulate resources. In the case where you already have
# an existing model with the same name as the desired RESTful resource you can set the +element_name+ value.
#
# class PersonResource < ActiveResource::Base
- # self.site = "http://api.people.com:3000/"
+ # self.site = "https://api.people.com"
# self.element_name = "person"
# end
#
# If your Active Resource object is required to use an HTTP proxy you can set the +proxy+ value which holds a URI.
#
# class PersonResource < ActiveResource::Base
- # self.site = "http://api.people.com:3000/"
- # self.proxy = "http://user:password@proxy.people.com:8080"
+ # self.site = "https://api.people.com"
+ # self.proxy = "https://user:password@proxy.people.com:8080"
# end
#
#
@@ -103,7 +103,7 @@ module ActiveResource
# You can validate resources client side by overriding validation methods in the base class.
#
# class Person < ActiveResource::Base
- # self.site = "http://api.people.com:3000/"
+ # self.site = "https://api.people.com"
# protected
# def validate
# errors.add("last", "has invalid characters") unless last =~ /[a-zA-Z]*/
@@ -114,47 +114,64 @@ module ActiveResource
#
# == Authentication
#
- # Many REST APIs will require authentication, usually in the form of basic
- # HTTP authentication. Authentication can be specified by:
+ # Many REST APIs require authentication. The HTTP spec describes two ways to
+ # make requests with a username and password (see RFC 2617).
#
- # === HTTP Basic Authentication
- # * putting the credentials in the URL for the +site+ variable.
+ # Basic authentication simply sends a username and password along with HTTP
+ # requests. These sensitive credentials are sent unencrypted, visible to
+ # any onlooker, so this scheme should only be used with SSL.
+ #
+ # Digest authentication sends a crytographic hash of the username, password,
+ # HTTP method, URI, and a single-use secret key provided by the server.
+ # Sensitive credentials aren't visible to onlookers, so digest authentication
+ # doesn't require SSL. However, this doesn't mean the connection is secure!
+ # Just the username and password.
+ #
+ # (You really, really want to use SSL. There's little reason not to.)
+ #
+ # === Picking an authentication scheme
+ #
+ # Basic authentication is the default. To switch to digest authentication,
+ # set +auth_type+ to +:digest+:
#
# class Person < ActiveResource::Base
- # self.site = "http://ryan:password@api.people.com:3000/"
+ # self.auth_type = :digest
# end
#
- # * defining +user+ and/or +password+ variables
+ # === Setting the username and password
+ #
+ # Set +user+ and +password+ on the class, or include them in the +site+ URL.
#
# class Person < ActiveResource::Base
- # self.site = "http://api.people.com:3000/"
+ # # Set user and password directly:
# self.user = "ryan"
# self.password = "password"
- # end
#
- # For obvious security reasons, it is probably best if such services are available
- # over HTTPS.
- #
- # Note: Some values cannot be provided in the URL passed to site. e.g. email addresses
- # as usernames. In those situations you should use the separate user and password option.
+ # # Or include them in the site:
+ # self.site = "https://ryan:password@api.people.com"
+ # end
#
# === Certificate Authentication
#
- # * End point uses an X509 certificate for authentication. <tt>See ssl_options=</tt> for all options.
+ # You can also authenticate using an X509 certificate. <tt>See ssl_options=</tt> for all options.
#
# class Person < ActiveResource::Base
# self.site = "https://secure.api.people.com/"
- # self.ssl_options = {:cert => OpenSSL::X509::Certificate.new(File.open(pem_file))
- # :key => OpenSSL::PKey::RSA.new(File.open(pem_file)),
- # :ca_path => "/path/to/OpenSSL/formatted/CA_Certs",
- # :verify_mode => OpenSSL::SSL::VERIFY_PEER}
+ #
+ # File.open(pem_file_path, 'rb') do |pem_file|
+ # self.ssl_options = {
+ # cert: OpenSSL::X509::Certificate.new(pem_file),
+ # key: OpenSSL::PKey::RSA.new(pem_file),
+ # ca_path: "/path/to/OpenSSL/formatted/CA_Certs",
+ # verify_mode: OpenSSL::SSL::VERIFY_PEER }
+ # end
# end
#
#
# == 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
@@ -163,15 +180,15 @@ module ActiveResource
# response code will be returned from the server which will raise an ActiveResource::ResourceNotFound
# exception.
#
- # # GET http://api.people.com:3000/people/999.json
+ # # GET https://api.people.com/people/999.json
# ryan = Person.find(999) # 404, raises ActiveResource::ResourceNotFound
#
#
# <tt>404</tt> is just one of the HTTP error response codes that Active Resource will handle with its own exception. The
# following HTTP response codes will also result in these exceptions:
#
- # * 200..399 - Valid response, no exception (other than 301, 302)
- # * 301, 302 - ActiveResource::Redirection
+ # * 200..399 - Valid response. No exceptions, other than these redirects:
+ # * 301, 302, 303, 307 - ActiveResource::Redirection
# * 400 - ActiveResource::BadRequest
# * 401 - ActiveResource::UnauthorizedAccess
# * 403 - ActiveResource::ForbiddenAccess
@@ -185,7 +202,7 @@ module ActiveResource
# * Other - ActiveResource::ConnectionError
#
# These custom exceptions allow you to deal with resource errors more naturally and with more precision
- # rather than returning a general HTTP error. For example:
+ # rather than returning a general HTTP error. For example:
#
# begin
# ryan = Person.find(my_id)
@@ -199,7 +216,7 @@ module ActiveResource
# an ActiveResource::MissingPrefixParam will be raised.
#
# class Comment < ActiveResource::Base
- # self.site = "http://someip.com/posts/:post_id/"
+ # self.site = "https://someip.com/posts/:post_id"
# end
#
# Comment.find(1)
@@ -208,8 +225,8 @@ module ActiveResource
# === Validation errors
#
# Active Resource supports validations on resources and will return errors if any of 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 <tt>422</tt> and an XML or JSON representation of the validation errors. The save operation will
+ # (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 <tt>422</tt> and an XML or JSON 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)
@@ -217,9 +234,9 @@ module ActiveResource
# ryan.save # => false
#
# # When
- # # PUT http://api.people.com:3000/people/1.json
+ # # PUT https://api.people.com/people/1.json
# # or
- # # PUT http://api.people.com:3000/people/1.json
+ # # PUT https://api.people.com/people/1.json
# # is requested with invalid values, the response is:
# #
# # Response (422):
@@ -240,7 +257,7 @@ module ActiveResource
# amount of time before Active Resource times out with the +timeout+ variable.
#
# class Person < ActiveResource::Base
- # self.site = "http://api.people.com:3000/"
+ # self.site = "https://api.people.com"
# self.timeout = 5
# end
#
@@ -383,22 +400,22 @@ module ActiveResource
@known_attributes ||= []
end
- # Gets the URI of the REST resources to map for this class. The site variable is required for
+ # Gets the URI of the REST resources to map for this class. The site variable is required for
# Active Resource's mapping to work.
def site
# Not using superclass_delegating_reader because don't want subclasses to modify superclass instance
#
# With superclass_delegating_reader
#
- # Parent.site = 'http://anonymous@test.com'
- # Subclass.site # => 'http://anonymous@test.com'
+ # Parent.site = 'https://anonymous@test.com'
+ # Subclass.site # => 'https://anonymous@test.com'
# Subclass.site.user = 'david'
- # Parent.site # => 'http://david@test.com'
+ # Parent.site # => 'https://david@test.com'
#
# Without superclass_delegating_reader (expected behavior)
#
- # Parent.site = 'http://anonymous@test.com'
- # Subclass.site # => 'http://anonymous@test.com'
+ # Parent.site = 'https://anonymous@test.com'
+ # Subclass.site # => 'https://anonymous@test.com'
# Subclass.site.user = 'david' # => TypeError: can't modify frozen object
#
if defined?(@site)
@@ -592,7 +609,7 @@ module ActiveResource
prefix(options)
end
- # An attribute reader for the source string for the resource path \prefix. This
+ # An attribute reader for the source string for the resource path \prefix. This
# method is regenerated at runtime based on what the \prefix is set to.
def prefix_source
prefix # generate #prefix and #prefix_source methods first
@@ -625,7 +642,7 @@ module ActiveResource
alias_method :set_element_name, :element_name= #:nodoc:
alias_method :set_collection_name, :collection_name= #:nodoc:
- # Gets the element path for the given ID in +id+. If the +query_options+ parameter is omitted, Rails
+ # Gets the element path for the given ID in +id+. If the +query_options+ parameter is omitted, Rails
# will split from the \prefix options.
#
# ==== Options
@@ -637,6 +654,10 @@ module ActiveResource
# Post.element_path(1)
# # => /posts/1.json
#
+ # class Comment < ActiveResource::Base
+ # self.site = "https://37s.sunrise.com/posts/:post_id"
+ # end
+ #
# Comment.element_path(1, :post_id => 5)
# # => /posts/5/comments/1.json
#
@@ -663,13 +684,17 @@ module ActiveResource
# Post.new_element_path
# # => /posts/new.json
#
+ # class Comment < ActiveResource::Base
+ # self.site = "https://37s.sunrise.com/posts/:post_id"
+ # end
+ #
# Comment.collection_path(:post_id => 5)
# # => /posts/5/comments/new.json
def new_element_path(prefix_options = {})
"#{prefix(prefix_options)}#{collection_name}/new.#{format.extension}"
end
- # Gets the collection path for the REST resources. If the +query_options+ parameter is omitted, Rails
+ # Gets the collection path for the REST resources. If the +query_options+ parameter is omitted, Rails
# will split from the +prefix_options+.
#
# ==== Options
@@ -717,8 +742,8 @@ module ActiveResource
# ryan = Person.new(:first => 'ryan')
# ryan.save
#
- # Returns the newly created resource. If a failure has occurred an
- # exception will be raised (see <tt>save</tt>). If the resource is invalid and
+ # Returns the newly created resource. If a failure has occurred an
+ # exception will be raised (see <tt>save</tt>). If the resource is invalid and
# has not been saved then <tt>valid?</tt> will return <tt>false</tt>,
# while <tt>new?</tt> will still return <tt>true</tt>.
#
@@ -739,11 +764,11 @@ module ActiveResource
self.new(attributes).tap { |resource| resource.save }
end
- # Core method for finding resources. Used similarly to Active Record's +find+ method.
+ # Core method for finding resources. Used similarly to Active Record's +find+ method.
#
# ==== Arguments
- # The first argument is considered to be the scope of the query. That is, how many
- # resources are returned from the request. It can be one of the following.
+ # The first argument is considered to be the scope of the query. That is, how many
+ # resources are returned from the request. It can be one of the following.
#
# * <tt>:one</tt> - Returns a single resource.
# * <tt>:first</tt> - Returns the first resource found.
@@ -826,7 +851,7 @@ module ActiveResource
find(:last, *args)
end
- # This is an alias for find(:all). You can pass in all the same
+ # This is an alias for find(:all). You can pass in all the same
# arguments to this method as you can to <tt>find(:all)</tt>
def all(*args)
find(:all, *args)
@@ -931,12 +956,12 @@ module ActiveResource
# Accepts a URI and creates the site URI from that.
def create_site_uri_from(site)
- site.is_a?(URI) ? site.dup : URI.parser.parse(site)
+ site.is_a?(URI) ? site.dup : URI.parse(site)
end
# Accepts a URI and creates the proxy URI from that.
def create_proxy_uri_from(proxy)
- proxy.is_a?(URI) ? proxy.dup : URI.parser.parse(proxy)
+ proxy.is_a?(URI) ? proxy.dup : URI.parse(proxy)
end
# contains a set of the current prefix parameters.
@@ -1007,7 +1032,7 @@ module ActiveResource
# not_ryan.new? # => true
#
# Any active resource member attributes will NOT be cloned, though all other
- # attributes are. This is to prevent the conflict between any +prefix_options+
+ # attributes are. This is to prevent the conflict between any +prefix_options+
# that refer to the original parent resource and the newly cloned parent
# resource that does not exist.
#
@@ -1023,7 +1048,7 @@ module ActiveResource
# Clone all attributes except the pk and any nested ARes
cloned = Hash[attributes.reject {|k,v| k == self.class.primary_key || v.is_a?(ActiveResource::Base)}.map { |k, v| [k, v.clone] }]
# Form the new resource - bypass initialize of resource with 'new' as that will call 'load' which
- # attempts to convert hashes into member objects and arrays into collections of objects. We want
+ # attempts to convert hashes into member objects and arrays into collections of objects. We want
# the raw objects to be cloned so we bypass load by directly setting the attributes hash.
resource = self.class.new({})
resource.prefix_options = self.prefix_options
@@ -1075,7 +1100,7 @@ module ActiveResource
attributes[self.class.primary_key] = id
end
- # Test for equality. Resource are equal if and only if +other+ is the same object or
+ # Test for equality. Resource are equal if and only if +other+ is the same object or
# is an instance of the same class, is not <tt>new?</tt>, and has the same +id+.
#
# ==== Examples
@@ -1131,7 +1156,7 @@ module ActiveResource
end
end
- # Saves (+POST+) or \updates (+PUT+) a resource. Delegates to +create+ if the object is \new,
+ # Saves (+POST+) or \updates (+PUT+) a resource. Delegates to +create+ if the object is \new,
# +update+ if it exists. If the response to the \save includes a body, it will be assumed that this body
# is Json for the final object as it looked after the \save (which would include attributes like +created_at+
# that weren't part of the original submit).
@@ -1182,7 +1207,7 @@ module ActiveResource
end
# Evaluates to <tt>true</tt> if this resource is not <tt>new?</tt> and is
- # found on the remote service. Using this method, you can check for
+ # found on the remote service. Using this method, you can check for
# resources that may have been deleted between the object's instantiation
# and actions on it.
#
@@ -1224,7 +1249,7 @@ module ActiveResource
end
# A method to manually load attributes from a \hash. Recursively loads collections of
- # resources. This method is called in +initialize+ and +create+ when a \hash of attributes
+ # resources. This method is called in +initialize+ and +create+ when a \hash of attributes
# is provided.
#
# ==== Examples
@@ -1281,12 +1306,12 @@ module ActiveResource
#
# Note: Unlike ActiveRecord::Base.update_attribute, this method <b>is</b>
# subject to normal validation routines as an update sends the whole body
- # of the resource in the request. (See Validations).
+ # of the resource in the request. (See Validations).
#
# As such, this method is equivalent to calling update_attributes with a single attribute/value pair.
#
# If the saving fails because of a connection or remote service error, an
- # exception will be raised. If saving fails because the resource is
+ # exception will be raised. If saving fails because the resource is
# invalid then <tt>false</tt> will be returned.
def update_attribute(name, value)
self.send("#{name}=".to_sym, value)
@@ -1297,7 +1322,7 @@ module ActiveResource
# and requests that the record be saved.
#
# If the saving fails because of a connection or remote service error, an
- # exception will be raised. If saving fails because the resource is
+ # exception will be raised. If saving fails because the resource is
# invalid then <tt>false</tt> will be returned.
#
# Note: Though this request can be made with a partial set of the
@@ -1384,6 +1409,10 @@ module ActiveResource
private
+ def read_attribute_for_serialization(n)
+ attributes[n]
+ end
+
# Determine whether the response is allowed to have a body per HTTP 1.1 spec section 4.4.1
def response_code_allows_body?(c)
!((100..199).include?(c) || [204,304].include?(c))
@@ -1401,7 +1430,7 @@ module ActiveResource
namespaces = module_names[0, module_names.size-1].map do |module_name|
receiver = receiver.const_get(module_name)
end
- const_args = RUBY_VERSION < "1.9" ? [resource_name] : [resource_name, false]
+ const_args = [resource_name, false]
if namespace = namespaces.reverse.detect { |ns| ns.const_defined?(*const_args) }
namespace.const_get(*const_args)
else
@@ -1413,7 +1442,7 @@ module ActiveResource
def find_or_create_resource_for(name)
resource_name = name.to_s.camelize
- const_args = RUBY_VERSION < "1.9" ? [resource_name] : [resource_name, false]
+ const_args = [resource_name, false]
if self.class.const_defined?(*const_args)
self.class.const_get(*const_args)
else
diff --git a/activeresource/lib/active_resource/connection.rb b/activeresource/lib/active_resource/connection.rb
index d923204dde..46060b6f74 100644
--- a/activeresource/lib/active_resource/connection.rb
+++ b/activeresource/lib/active_resource/connection.rb
@@ -39,14 +39,14 @@ module ActiveResource
# Set URI for remote service.
def site=(site)
- @site = site.is_a?(URI) ? site : URI.parser.parse(site)
+ @site = site.is_a?(URI) ? site : URI.parse(site)
@user = URI.parser.unescape(@site.user) if @site.user
@password = URI.parser.unescape(@site.password) if @site.password
end
# Set the proxy for remote service.
def proxy=(proxy)
- @proxy = proxy.is_a?(URI) ? proxy : URI.parser.parse(proxy)
+ @proxy = proxy.is_a?(URI) ? proxy : URI.parse(proxy)
end
# Sets the user for remote service.
@@ -122,7 +122,7 @@ module ActiveResource
# Handles response and error codes from the remote service.
def handle_response(response)
case response.code.to_i
- when 301,302
+ when 301, 302, 303, 307
raise(Redirection.new(response))
when 200...400
response
@@ -166,38 +166,28 @@ module ActiveResource
end
def configure_http(http)
- http = apply_ssl_options(http)
-
- # Net::HTTP timeouts default to 60 seconds.
- if @timeout
- http.open_timeout = @timeout
- http.read_timeout = @timeout
+ apply_ssl_options(http).tap do |https|
+ # Net::HTTP timeouts default to 60 seconds.
+ if defined? @timeout
+ https.open_timeout = @timeout
+ https.read_timeout = @timeout
+ end
end
-
- http
end
def apply_ssl_options(http)
- return http unless @site.is_a?(URI::HTTPS)
-
- http.use_ssl = true
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
- return http unless defined?(@ssl_options)
-
- http.ca_path = @ssl_options[:ca_path] if @ssl_options[:ca_path]
- http.ca_file = @ssl_options[:ca_file] if @ssl_options[:ca_file]
+ http.tap do |https|
+ # Skip config if site is already a https:// URI.
+ if defined? @ssl_options
+ http.use_ssl = true
- http.cert = @ssl_options[:cert] if @ssl_options[:cert]
- http.key = @ssl_options[:key] if @ssl_options[:key]
+ # Default to no cert verification (WTF? FIXME)
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
- http.cert_store = @ssl_options[:cert_store] if @ssl_options[:cert_store]
- http.ssl_timeout = @ssl_options[:ssl_timeout] if @ssl_options[:ssl_timeout]
-
- http.verify_mode = @ssl_options[:verify_mode] if @ssl_options[:verify_mode]
- http.verify_callback = @ssl_options[:verify_callback] if @ssl_options[:verify_callback]
- http.verify_depth = @ssl_options[:verify_depth] if @ssl_options[:verify_depth]
-
- http
+ # All the SSL options have corresponding http settings.
+ @ssl_options.each { |key, value| http.send "#{key}=", value }
+ end
+ end
end
def default_header
@@ -238,8 +228,11 @@ module ActiveResource
def digest_auth_header(http_method, uri)
params = extract_params_from_response
+ request_uri = uri.path
+ request_uri << "?#{uri.query}" if uri.query
+
ha1 = Digest::MD5.hexdigest("#{@user}:#{params['realm']}:#{@password}")
- ha2 = Digest::MD5.hexdigest("#{http_method.to_s.upcase}:#{uri.path}")
+ ha2 = Digest::MD5.hexdigest("#{http_method.to_s.upcase}:#{request_uri}")
params.merge!('cnonce' => client_nonce)
request_digest = Digest::MD5.hexdigest([ha1, params['nonce'], "0", params['cnonce'], params['qop'], ha2].join(":"))
diff --git a/activeresource/lib/active_resource/custom_methods.rb b/activeresource/lib/active_resource/custom_methods.rb
index c1931b2758..a0eb28ed13 100644
--- a/activeresource/lib/active_resource/custom_methods.rb
+++ b/activeresource/lib/active_resource/custom_methods.rb
@@ -2,7 +2,7 @@ require 'active_support/core_ext/object/blank'
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,
+ # 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 },
@@ -20,10 +20,10 @@ module ActiveResource
# standard methods.
#
# class Person < ActiveResource::Base
- # self.site = "http://37s.sunrise.i:3000"
+ # self.site = "https://37s.sunrise.com"
# end
#
- # Person.new(:name => 'Ryan).post(:register) # POST /people/new/register.json
+ # Person.new(:name => 'Ryan').post(:register) # POST /people/new/register.json
# # => { :id => 1, :name => 'Ryan' }
#
# Person.find(1).put(:promote, :position => 'Manager') # PUT /people/1/promote.json
@@ -85,37 +85,35 @@ module ActiveResource
end
end
- module InstanceMethods
- def get(method_name, options = {})
- self.class.format.decode(connection.get(custom_method_element_url(method_name, options), self.class.headers).body)
- end
+ def get(method_name, options = {})
+ self.class.format.decode(connection.get(custom_method_element_url(method_name, options), self.class.headers).body)
+ end
- def post(method_name, options = {}, body = nil)
- request_body = body.blank? ? encode : body
- if new?
- connection.post(custom_method_new_element_url(method_name, options), request_body, self.class.headers)
- else
- connection.post(custom_method_element_url(method_name, options), request_body, self.class.headers)
- end
+ def post(method_name, options = {}, body = nil)
+ request_body = body.blank? ? encode : body
+ if new?
+ connection.post(custom_method_new_element_url(method_name, options), request_body, self.class.headers)
+ else
+ connection.post(custom_method_element_url(method_name, options), request_body, self.class.headers)
end
+ end
- def put(method_name, options = {}, body = '')
- connection.put(custom_method_element_url(method_name, options), body, self.class.headers)
- end
+ def put(method_name, options = {}, body = '')
+ connection.put(custom_method_element_url(method_name, options), body, self.class.headers)
+ end
- def delete(method_name, options = {})
- connection.delete(custom_method_element_url(method_name, options), self.class.headers)
- end
+ def delete(method_name, options = {})
+ connection.delete(custom_method_element_url(method_name, options), self.class.headers)
+ end
- private
- def custom_method_element_url(method_name, options = {})
- "#{self.class.prefix(prefix_options)}#{self.class.collection_name}/#{id}/#{method_name}.#{self.class.format.extension}#{self.class.__send__(:query_string, options)}"
- end
+ private
+ def custom_method_element_url(method_name, options = {})
+ "#{self.class.prefix(prefix_options)}#{self.class.collection_name}/#{id}/#{method_name}.#{self.class.format.extension}#{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}.#{self.class.format.extension}#{self.class.__send__(:query_string, options)}"
- end
- end
+ def custom_method_new_element_url(method_name, options = {})
+ "#{self.class.prefix(prefix_options)}#{self.class.collection_name}/new/#{method_name}.#{self.class.format.extension}#{self.class.__send__(:query_string, options)}"
+ end
end
end
diff --git a/activeresource/lib/active_resource/exceptions.rb b/activeresource/lib/active_resource/exceptions.rb
index 6b953b28ad..51bede3bd0 100644
--- a/activeresource/lib/active_resource/exceptions.rb
+++ b/activeresource/lib/active_resource/exceptions.rb
@@ -33,35 +33,45 @@ module ActiveResource
# 3xx Redirection
class Redirection < ConnectionError # :nodoc:
- def to_s; response['Location'] ? "#{super} => #{response['Location']}" : super; end
+ def to_s
+ response['Location'] ? "#{super} => #{response['Location']}" : super
+ end
end
- # Raised when ...
- class MissingPrefixParam < ArgumentError; end # :nodoc:
+ class MissingPrefixParam < ArgumentError # :nodoc:
+ end
# 4xx Client Error
- class ClientError < ConnectionError; end # :nodoc:
+ class ClientError < ConnectionError # :nodoc:
+ end
# 400 Bad Request
- class BadRequest < ClientError; end # :nodoc
+ class BadRequest < ClientError # :nodoc:
+ end
# 401 Unauthorized
- class UnauthorizedAccess < ClientError; end # :nodoc
+ class UnauthorizedAccess < ClientError # :nodoc:
+ end
# 403 Forbidden
- class ForbiddenAccess < ClientError; end # :nodoc
+ class ForbiddenAccess < ClientError # :nodoc:
+ end
# 404 Not Found
- class ResourceNotFound < ClientError; end # :nodoc:
+ class ResourceNotFound < ClientError # :nodoc:
+ end
# 409 Conflict
- class ResourceConflict < ClientError; end # :nodoc:
+ class ResourceConflict < ClientError # :nodoc:
+ end
# 410 Gone
- class ResourceGone < ClientError; end # :nodoc:
+ class ResourceGone < ClientError # :nodoc:
+ end
# 5xx Server Error
- class ServerError < ConnectionError; end # :nodoc:
+ class ServerError < ConnectionError # :nodoc:
+ end
# 405 Method Not Allowed
class MethodNotAllowed < ClientError # :nodoc:
diff --git a/activeresource/lib/active_resource/http_mock.rb b/activeresource/lib/active_resource/http_mock.rb
index 36f52d61d3..666b961f87 100644
--- a/activeresource/lib/active_resource/http_mock.rb
+++ b/activeresource/lib/active_resource/http_mock.rb
@@ -4,7 +4,7 @@ require 'active_support/core_ext/object/inclusion'
module ActiveResource
class InvalidRequestError < StandardError; end #:nodoc:
- # One thing that has always been a pain with remote web services is testing. The HttpMock
+ # One thing that has always been a pain with remote web services is testing. The HttpMock
# class makes it easy to test your Active Resource models by creating a set of mock responses to specific
# requests.
#
@@ -15,17 +15,17 @@ module ActiveResource
#
# mock.http_method(path, request_headers = {}, body = nil, status = 200, response_headers = {})
#
- # * <tt>http_method</tt> - The HTTP method to listen for. This can be +get+, +post+, +put+, +delete+ or
+ # * <tt>http_method</tt> - The HTTP method to listen for. This can be +get+, +post+, +put+, +delete+ or
# +head+.
# * <tt>path</tt> - A string, starting with a "/", defining the URI that is expected to be
# called.
- # * <tt>request_headers</tt> - Headers that are expected along with the request. This argument uses a
- # hash format, such as <tt>{ "Content-Type" => "application/json" }</tt>. This mock will only trigger
+ # * <tt>request_headers</tt> - Headers that are expected along with the request. This argument uses a
+ # hash format, such as <tt>{ "Content-Type" => "application/json" }</tt>. This mock will only trigger
# if your tests sends a request with identical headers.
- # * <tt>body</tt> - The data to be returned. This should be a string of Active Resource parseable content,
+ # * <tt>body</tt> - The data to be returned. This should be a string of Active Resource parseable content,
# such as Json.
# * <tt>status</tt> - The HTTP response code, as an integer, to return with the response.
- # * <tt>response_headers</tt> - Headers to be returned with the response. Uses the same hash format as
+ # * <tt>response_headers</tt> - Headers to be returned with the response. Uses the same hash format as
# <tt>request_headers</tt> listed above.
#
# In order for a mock to deliver its content, the incoming request must match by the <tt>http_method</tt>,
@@ -291,12 +291,9 @@ module ActiveResource
if resp_cls && !resp_cls.body_permitted?
@body = nil
end
-
- if @body.nil?
- self['Content-Length'] = "0"
- else
- self['Content-Length'] = body.size.to_s
- end
+
+ self['Content-Length'] = @body.nil? ? "0" : body.size.to_s
+
end
# Returns true if code is 2xx,
diff --git a/activeresource/lib/active_resource/validations.rb b/activeresource/lib/active_resource/validations.rb
index 264c5fed8c..c11908eb86 100644
--- a/activeresource/lib/active_resource/validations.rb
+++ b/activeresource/lib/active_resource/validations.rb
@@ -55,7 +55,7 @@ module ActiveResource
# Module to support validation and errors with Active Resource objects. The module overrides
# Base#save to rescue ActiveResource::ResourceInvalid exceptions and parse the errors returned
# in the web service response. The module also adds an +errors+ collection that mimics the interface
- # of the errors provided by ActiveRecord::Errors.
+ # of the errors provided by ActiveModel::Errors.
#
# ==== Example
#
diff --git a/activeresource/lib/active_resource/version.rb b/activeresource/lib/active_resource/version.rb
index d53374b261..d02784bd5d 100644
--- a/activeresource/lib/active_resource/version.rb
+++ b/activeresource/lib/active_resource/version.rb
@@ -1,7 +1,7 @@
module ActiveResource
module VERSION #:nodoc:
- MAJOR = 3
- MINOR = 2
+ MAJOR = 4
+ MINOR = 0
TINY = 0
PRE = "beta"