aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib')
-rw-r--r--actionpack/lib/abstract_controller/callbacks.rb14
-rw-r--r--actionpack/lib/abstract_controller/layouts.rb2
-rw-r--r--actionpack/lib/action_controller/metal/force_ssl.rb18
-rw-r--r--actionpack/lib/action_controller/metal/http_authentication.rb4
-rw-r--r--actionpack/lib/action_controller/metal/mime_responds.rb2
-rw-r--r--actionpack/lib/action_controller/metal/rendering.rb2
-rw-r--r--actionpack/lib/action_controller/metal/responder.rb13
-rw-r--r--actionpack/lib/action_controller/test_case.rb7
-rw-r--r--actionpack/lib/action_dispatch/http/request.rb6
-rw-r--r--actionpack/lib/action_dispatch/middleware/callbacks.rb12
-rw-r--r--actionpack/lib/action_dispatch/routing.rb15
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb132
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb9
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb26
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb4
-rw-r--r--actionpack/lib/action_view/helpers/form_tag_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/tags/base.rb6
-rw-r--r--actionpack/lib/action_view/helpers/url_helper.rb8
-rw-r--r--actionpack/lib/action_view/lookup_context.rb14
-rw-r--r--actionpack/lib/action_view/renderer/abstract_renderer.rb2
-rw-r--r--actionpack/lib/action_view/renderer/template_renderer.rb3
-rw-r--r--actionpack/lib/action_view/template.rb1
-rw-r--r--actionpack/lib/action_view/template/handlers/erb.rb4
23 files changed, 181 insertions, 125 deletions
diff --git a/actionpack/lib/abstract_controller/callbacks.rb b/actionpack/lib/abstract_controller/callbacks.rb
index 44c9ea34ba..c0fa28cae9 100644
--- a/actionpack/lib/abstract_controller/callbacks.rb
+++ b/actionpack/lib/abstract_controller/callbacks.rb
@@ -46,7 +46,7 @@ module AbstractController
# callbacks. Note that skipping uses Ruby equality, so it's
# impossible to skip a callback defined using an anonymous proc
# using #skip_filter
- def skip_filter(*names, &blk)
+ def skip_filter(*names)
skip_before_filter(*names)
skip_after_filter(*names)
skip_around_filter(*names)
@@ -64,7 +64,7 @@ module AbstractController
# ==== Block Parameters
# * <tt>name</tt> - The callback to be added
# * <tt>options</tt> - A hash of options to be used when adding the callback
- def _insert_callbacks(callbacks, block)
+ def _insert_callbacks(callbacks, block = nil)
options = callbacks.last.is_a?(Hash) ? callbacks.pop : {}
_normalize_callback_options(options)
callbacks.push(block) if block
@@ -90,7 +90,7 @@ module AbstractController
##
# :method: skip_before_filter
#
- # :call-seq: skip_before_filter(names, block)
+ # :call-seq: skip_before_filter(names)
#
# Skip a before filter. See _insert_callbacks for parameter details.
@@ -118,7 +118,7 @@ module AbstractController
##
# :method: skip_after_filter
#
- # :call-seq: skip_after_filter(names, block)
+ # :call-seq: skip_after_filter(names)
#
# Skip an after filter. See _insert_callbacks for parameter details.
@@ -146,7 +146,7 @@ module AbstractController
##
# :method: skip_around_filter
#
- # :call-seq: skip_around_filter(names, block)
+ # :call-seq: skip_around_filter(names)
#
# Skip an around filter. See _insert_callbacks for parameter details.
@@ -179,8 +179,8 @@ module AbstractController
# Skip a before, after or around filter. See _insert_callbacks
# for details on the allowed parameters.
- def skip_#{filter}_filter(*names, &blk) # def skip_before_filter(*names, &blk)
- _insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
+ def skip_#{filter}_filter(*names) # def skip_before_filter(*names)
+ _insert_callbacks(names) do |name, options| # _insert_callbacks(names) do |name, options|
skip_callback(:process_action, :#{filter}, name, options) # skip_callback(:process_action, :before, name, options)
end # end
end # end
diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb
index 6a6387632c..aa39e21ba9 100644
--- a/actionpack/lib/abstract_controller/layouts.rb
+++ b/actionpack/lib/abstract_controller/layouts.rb
@@ -322,7 +322,7 @@ module AbstractController
super
if _include_layout?(options)
- layout = options.key?(:layout) ? options.delete(:layout) : :default
+ layout = options.delete(:layout) { :default }
options[:layout] = _layout_for_option(layout)
end
end
diff --git a/actionpack/lib/action_controller/metal/force_ssl.rb b/actionpack/lib/action_controller/metal/force_ssl.rb
index 69e37d8713..a1e40fc4e0 100644
--- a/actionpack/lib/action_controller/metal/force_ssl.rb
+++ b/actionpack/lib/action_controller/metal/force_ssl.rb
@@ -18,15 +18,29 @@ module ActionController
# Force the request to this particular controller or specified actions to be
# under HTTPS protocol.
#
- # Note that this method will not be effective on development environment.
+ # If you need to disable this for any reason (e.g. development) then you can use
+ # an +:if+ or +:unless+ condition.
+ #
+ # class AccountsController < ApplicationController
+ # force_ssl :if => :ssl_configured?
+ #
+ # def ssl_configured?
+ # !Rails.env.development?
+ # end
+ # end
#
# ==== Options
+ # * <tt>host</tt> - Redirect to a different host name
# * <tt>only</tt> - The callback should be run only for this action
# * <tt>except<tt> - The callback should be run for all actions except this action
+ # * <tt>if</tt> - A symbol naming an instance method or a proc; the callback
+ # will be called only when it returns a true value.
+ # * <tt>unless</tt> - A symbol naming an instance method or a proc; the callback
+ # will be called only when it returns a false value.
def force_ssl(options = {})
host = options.delete(:host)
before_filter(options) do
- if !request.ssl? && !Rails.env.development?
+ unless request.ssl?
redirect_options = {:protocol => 'https://', :status => :moved_permanently}
redirect_options.merge!(:host => host) if host
redirect_options.merge!(:params => request.query_parameters)
diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb
index 3d46163b74..b8b43ea9ef 100644
--- a/actionpack/lib/action_controller/metal/http_authentication.rb
+++ b/actionpack/lib/action_controller/metal/http_authentication.rb
@@ -279,7 +279,7 @@ module ActionController
#
# An implementation might choose not to accept a previously used nonce or a previously used digest, in order to
# protect against a replay attack. Or, an implementation might choose to use one-time nonces or digests for
- # POST or PUT requests and a time-stamp for GET requests. For more details on the issues involved see Section 4
+ # POST, PUT, or PATCH requests and a time-stamp for GET requests. For more details on the issues involved see Section 4
# of this document.
#
# The nonce is opaque to the client. Composed of Time, and hash of Time with secret
@@ -293,7 +293,7 @@ module ActionController
end
# Might want a shorter timeout depending on whether the request
- # is a PUT or POST, and if client is browser or web service.
+ # is a PATCH, PUT, or POST, and if client is browser or web service.
# Can be much shorter if the Stale directive is implemented. This would
# allow a user to use new nonce without prompting user again for their
# username and password.
diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb
index 80ecc16d53..55de7e7d8e 100644
--- a/actionpack/lib/action_controller/metal/mime_responds.rb
+++ b/actionpack/lib/action_controller/metal/mime_responds.rb
@@ -280,7 +280,7 @@ module ActionController #:nodoc:
if format
self.content_type ||= format.to_s
- lookup_context.freeze_formats([format.to_sym])
+ lookup_context.formats = [format.to_sym]
collector
else
head :not_acceptable
diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb
index a677cdf15d..c5e7d4e357 100644
--- a/actionpack/lib/action_controller/metal/rendering.rb
+++ b/actionpack/lib/action_controller/metal/rendering.rb
@@ -14,7 +14,7 @@ module ActionController
def render(*args) #:nodoc:
raise ::AbstractController::DoubleRenderError if response_body
super
- self.content_type ||= Mime[formats.first].to_s
+ self.content_type ||= Mime[lookup_context.rendered_format].to_s
response_body
end
diff --git a/actionpack/lib/action_controller/metal/responder.rb b/actionpack/lib/action_controller/metal/responder.rb
index daa1ddd65f..ccda01ed44 100644
--- a/actionpack/lib/action_controller/metal/responder.rb
+++ b/actionpack/lib/action_controller/metal/responder.rb
@@ -53,7 +53,7 @@ module ActionController #:nodoc:
# end
# end
#
- # The same happens for PUT and DELETE requests.
+ # The same happens for PATCH/PUT and DELETE requests.
#
# === Nested resources
#
@@ -116,8 +116,9 @@ module ActionController #:nodoc:
class Responder
attr_reader :controller, :request, :format, :resource, :resources, :options
- ACTIONS_FOR_VERBS = {
+ DEFAULT_ACTIONS_FOR_VERBS = {
:post => :new,
+ :patch => :edit,
:put => :edit
}
@@ -132,7 +133,7 @@ module ActionController #:nodoc:
end
delegate :head, :render, :redirect_to, :to => :controller
- delegate :get?, :post?, :put?, :delete?, :to => :request
+ delegate :get?, :post?, :patch?, :put?, :delete?, :to => :request
# Undefine :to_json and :to_yaml since it's defined on Object
undef_method(:to_json) if method_defined?(:to_json)
@@ -259,11 +260,11 @@ module ActionController #:nodoc:
resource.respond_to?(:errors) && !resource.errors.empty?
end
- # By default, render the <code>:edit</code> action for HTML requests with failure, unless
- # the verb is POST.
+ # By default, render the <code>:edit</code> action for HTML requests with errors, unless
+ # the verb was POST.
#
def default_action
- @action ||= ACTIONS_FOR_VERBS[request.request_method_symbol]
+ @action ||= DEFAULT_ACTIONS_FOR_VERBS[request.request_method_symbol]
end
def resource_errors
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index 1e226fc336..3509e74d5e 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -225,7 +225,7 @@ module ActionController
# == Basic example
#
# Functional tests are written as follows:
- # 1. First, one uses the +get+, +post+, +put+, +delete+ or +head+ method to simulate
+ # 1. First, one uses the +get+, +post+, +patch+, +put+, +delete+ or +head+ method to simulate
# an HTTP request.
# 2. Then, one asserts whether the current state is as expected. "State" can be anything:
# the controller's HTTP response, the database contents, etc.
@@ -392,6 +392,11 @@ module ActionController
process(action, "POST", *args)
end
+ # Executes a request simulating PATCH HTTP method and set/volley the response
+ def patch(action, *args)
+ process(action, "PATCH", *args)
+ end
+
# Executes a request simulating PUT HTTP method and set/volley the response
def put(action, *args)
process(action, "PUT", *args)
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index 0a0ebe7fad..de014a9c00 100644
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -97,6 +97,12 @@ module ActionDispatch
HTTP_METHOD_LOOKUP[request_method] == :post
end
+ # Is this a PATCH request?
+ # Equivalent to <tt>request.request_method == :patch</tt>.
+ def patch?
+ HTTP_METHOD_LOOKUP[request_method] == :patch
+ end
+
# Is this a PUT request?
# Equivalent to <tt>request.request_method_symbol == :put</tt>.
def put?
diff --git a/actionpack/lib/action_dispatch/middleware/callbacks.rb b/actionpack/lib/action_dispatch/middleware/callbacks.rb
index 8c0f4052ec..338b116940 100644
--- a/actionpack/lib/action_dispatch/middleware/callbacks.rb
+++ b/actionpack/lib/action_dispatch/middleware/callbacks.rb
@@ -5,7 +5,7 @@ module ActionDispatch
class Callbacks
include ActiveSupport::Callbacks
- define_callbacks :call, :rescuable => true
+ define_callbacks :call
class << self
delegate :to_prepare, :to_cleanup, :to => "ActionDispatch::Reloader"
@@ -24,9 +24,15 @@ module ActionDispatch
end
def call(env)
- run_callbacks :call do
- @app.call(env)
+ error = nil
+ result = run_callbacks :call do
+ begin
+ @app.call(env)
+ rescue => error
+ end
end
+ raise error if error
+ result
end
end
end
diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb
index 107fe80d1f..38a0270151 100644
--- a/actionpack/lib/action_dispatch/routing.rb
+++ b/actionpack/lib/action_dispatch/routing.rb
@@ -182,10 +182,13 @@ module ActionDispatch
#
# == HTTP Methods
#
- # Using the <tt>:via</tt> option when specifying a route allows you to restrict it to a specific HTTP method.
- # Possible values are <tt>:post</tt>, <tt>:get</tt>, <tt>:put</tt>, <tt>:delete</tt> and <tt>:any</tt>.
- # If your route needs to respond to more than one method you can use an array, e.g. <tt>[ :get, :post ]</tt>.
- # The default value is <tt>:any</tt> which means that the route will respond to any of the HTTP methods.
+ # Using the <tt>:via</tt> option when specifying a route allows you to
+ # restrict it to a specific HTTP method. Possible values are <tt>:post</tt>,
+ # <tt>:get</tt>, <tt>:patch</tt>, <tt>:put</tt>, <tt>:delete</tt> and
+ # <tt>:any</tt>. If your route needs to respond to more than one method you
+ # can use an array, e.g. <tt>[ :get, :post ]</tt>. The default value is
+ # <tt>:any</tt> which means that the route will respond to any of the HTTP
+ # methods.
#
# Examples:
#
@@ -198,7 +201,7 @@ module ActionDispatch
# === HTTP helper methods
#
# An alternative method of specifying which HTTP method a route should respond to is to use the helper
- # methods <tt>get</tt>, <tt>post</tt>, <tt>put</tt> and <tt>delete</tt>.
+ # methods <tt>get</tt>, <tt>post</tt>, <tt>patch</tt>, <tt>put</tt> and <tt>delete</tt>.
#
# Examples:
#
@@ -283,6 +286,6 @@ module ActionDispatch
autoload :PolymorphicRoutes, 'action_dispatch/routing/polymorphic_routes'
SEPARATORS = %w( / . ? ) #:nodoc:
- HTTP_METHODS = [:get, :head, :post, :put, :delete, :options] #:nodoc:
+ HTTP_METHODS = [:get, :head, :post, :patch, :put, :delete, :options] #:nodoc:
end
end
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index cf9c0d7b6a..4f55537fe2 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -465,7 +465,7 @@ module ActionDispatch
#
# Example:
#
- # get 'bacon', :to => 'food#bacon'
+ # get 'bacon', :to => 'food#bacon'
def get(*args, &block)
map_method(:get, args, &block)
end
@@ -475,17 +475,27 @@ module ActionDispatch
#
# Example:
#
- # post 'bacon', :to => 'food#bacon'
+ # post 'bacon', :to => 'food#bacon'
def post(*args, &block)
map_method(:post, args, &block)
end
+ # Define a route that only recognizes HTTP PATCH.
+ # For supported arguments, see <tt>Base#match</tt>.
+ #
+ # Example:
+ #
+ # patch 'bacon', :to => 'food#bacon'
+ def patch(*args, &block)
+ map_method(:patch, args, &block)
+ end
+
# Define a route that only recognizes HTTP PUT.
# For supported arguments, see <tt>Base#match</tt>.
#
# Example:
#
- # put 'bacon', :to => 'food#bacon'
+ # put 'bacon', :to => 'food#bacon'
def put(*args, &block)
map_method(:put, args, &block)
end
@@ -495,7 +505,7 @@ module ActionDispatch
#
# Example:
#
- # delete 'broccoli', :to => 'food#broccoli'
+ # delete 'broccoli', :to => 'food#broccoli'
def delete(*args, &block)
map_method(:delete, args, &block)
end
@@ -522,13 +532,13 @@ module ActionDispatch
# This will create a number of routes for each of the posts and comments
# controller. For <tt>Admin::PostsController</tt>, Rails will create:
#
- # GET /admin/posts
- # GET /admin/posts/new
- # POST /admin/posts
- # GET /admin/posts/1
- # GET /admin/posts/1/edit
- # PUT /admin/posts/1
- # DELETE /admin/posts/1
+ # GET /admin/posts
+ # GET /admin/posts/new
+ # POST /admin/posts
+ # GET /admin/posts/1
+ # GET /admin/posts/1/edit
+ # PATCH/PUT /admin/posts/1
+ # DELETE /admin/posts/1
#
# If you want to route /posts (without the prefix /admin) to
# <tt>Admin::PostsController</tt>, you could use
@@ -556,13 +566,13 @@ module ActionDispatch
# not use scope. In the last case, the following paths map to
# +PostsController+:
#
- # GET /admin/posts
- # GET /admin/posts/new
- # POST /admin/posts
- # GET /admin/posts/1
- # GET /admin/posts/1/edit
- # PUT /admin/posts/1
- # DELETE /admin/posts/1
+ # GET /admin/posts
+ # GET /admin/posts/new
+ # POST /admin/posts
+ # GET /admin/posts/1
+ # GET /admin/posts/1/edit
+ # PATCH/PUT /admin/posts/1
+ # DELETE /admin/posts/1
module Scoping
# Scopes a set of routes to the given default options.
#
@@ -651,13 +661,13 @@ module ActionDispatch
#
# This generates the following routes:
#
- # admin_posts GET /admin/posts(.:format) admin/posts#index
- # admin_posts POST /admin/posts(.:format) admin/posts#create
- # new_admin_post GET /admin/posts/new(.:format) admin/posts#new
- # edit_admin_post GET /admin/posts/:id/edit(.:format) admin/posts#edit
- # admin_post GET /admin/posts/:id(.:format) admin/posts#show
- # admin_post PUT /admin/posts/:id(.:format) admin/posts#update
- # admin_post DELETE /admin/posts/:id(.:format) admin/posts#destroy
+ # admin_posts GET /admin/posts(.:format) admin/posts#index
+ # admin_posts POST /admin/posts(.:format) admin/posts#create
+ # new_admin_post GET /admin/posts/new(.:format) admin/posts#new
+ # edit_admin_post GET /admin/posts/:id/edit(.:format) admin/posts#edit
+ # admin_post GET /admin/posts/:id(.:format) admin/posts#show
+ # admin_post PATCH/PUT /admin/posts/:id(.:format) admin/posts#update
+ # admin_post DELETE /admin/posts/:id(.:format) admin/posts#destroy
#
# === Options
#
@@ -972,12 +982,12 @@ module ActionDispatch
# the +GeoCoders+ controller (note that the controller is named after
# the plural):
#
- # GET /geocoder/new
- # POST /geocoder
- # GET /geocoder
- # GET /geocoder/edit
- # PUT /geocoder
- # DELETE /geocoder
+ # GET /geocoder/new
+ # POST /geocoder
+ # GET /geocoder
+ # GET /geocoder/edit
+ # PATCH/PUT /geocoder
+ # DELETE /geocoder
#
# === Options
# Takes same options as +resources+.
@@ -1000,9 +1010,12 @@ module ActionDispatch
end if parent_resource.actions.include?(:new)
member do
- get :edit if parent_resource.actions.include?(:edit)
- get :show if parent_resource.actions.include?(:show)
- put :update if parent_resource.actions.include?(:update)
+ get :edit if parent_resource.actions.include?(:edit)
+ get :show if parent_resource.actions.include?(:show)
+ if parent_resource.actions.include?(:update)
+ patch :update
+ put :update
+ end
delete :destroy if parent_resource.actions.include?(:destroy)
end
end
@@ -1020,13 +1033,13 @@ module ActionDispatch
# creates seven different routes in your application, all mapping to
# the +Photos+ controller:
#
- # GET /photos
- # GET /photos/new
- # POST /photos
- # GET /photos/:id
- # GET /photos/:id/edit
- # PUT /photos/:id
- # DELETE /photos/:id
+ # GET /photos
+ # GET /photos/new
+ # POST /photos
+ # GET /photos/:id
+ # GET /photos/:id/edit
+ # PATCH/PUT /photos/:id
+ # DELETE /photos/:id
#
# Resources can also be nested infinitely by using this block syntax:
#
@@ -1036,13 +1049,13 @@ module ActionDispatch
#
# This generates the following comments routes:
#
- # GET /photos/:photo_id/comments
- # GET /photos/:photo_id/comments/new
- # POST /photos/:photo_id/comments
- # GET /photos/:photo_id/comments/:id
- # GET /photos/:photo_id/comments/:id/edit
- # PUT /photos/:photo_id/comments/:id
- # DELETE /photos/:photo_id/comments/:id
+ # GET /photos/:photo_id/comments
+ # GET /photos/:photo_id/comments/new
+ # POST /photos/:photo_id/comments
+ # GET /photos/:photo_id/comments/:id
+ # GET /photos/:photo_id/comments/:id/edit
+ # PATCH/PUT /photos/:photo_id/comments/:id
+ # DELETE /photos/:photo_id/comments/:id
#
# === Options
# Takes same options as <tt>Base#match</tt> as well as:
@@ -1104,13 +1117,13 @@ module ActionDispatch
#
# The +comments+ resource here will have the following routes generated for it:
#
- # post_comments GET /posts/:post_id/comments(.:format)
- # post_comments POST /posts/:post_id/comments(.:format)
- # new_post_comment GET /posts/:post_id/comments/new(.:format)
- # edit_comment GET /sekret/comments/:id/edit(.:format)
- # comment GET /sekret/comments/:id(.:format)
- # comment PUT /sekret/comments/:id(.:format)
- # comment DELETE /sekret/comments/:id(.:format)
+ # post_comments GET /posts/:post_id/comments(.:format)
+ # post_comments POST /posts/:post_id/comments(.:format)
+ # new_post_comment GET /posts/:post_id/comments/new(.:format)
+ # edit_comment GET /sekret/comments/:id/edit(.:format)
+ # comment GET /sekret/comments/:id(.:format)
+ # comment PATCH/PUT /sekret/comments/:id(.:format)
+ # comment DELETE /sekret/comments/:id(.:format)
#
# === Examples
#
@@ -1139,9 +1152,12 @@ module ActionDispatch
end if parent_resource.actions.include?(:new)
member do
- get :edit if parent_resource.actions.include?(:edit)
- get :show if parent_resource.actions.include?(:show)
- put :update if parent_resource.actions.include?(:update)
+ get :edit if parent_resource.actions.include?(:edit)
+ get :show if parent_resource.actions.include?(:show)
+ if parent_resource.actions.include?(:update)
+ patch :update
+ put :update
+ end
delete :destroy if parent_resource.actions.include?(:destroy)
end
end
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 6c189fdba6..57c6972078 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -9,6 +9,12 @@ require 'action_controller/metal/exceptions'
module ActionDispatch
module Routing
class RouteSet #:nodoc:
+ # Since the router holds references to many parts of the system
+ # like engines, controllers and the application itself, inspecting
+ # the route set can actually be really slow, therefore we default
+ # alias inspect to to_s.
+ alias inspect to_s
+
PARAMETERS_KEY = 'action_dispatch.request.path_parameters'
class Dispatcher #:nodoc:
@@ -251,8 +257,7 @@ module ActionDispatch
def eval_block(block)
if block.arity == 1
raise "You are using the old router DSL which has been removed in Rails 3.1. " <<
- "Please check how to update your routes file at: http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/ " <<
- "or add the rails_legacy_mapper gem to your Gemfile"
+ "Please check how to update your routes file at: http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/"
end
mapper = Mapper.new(self)
if default_scope
diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb
index 0287e7728b..69d54f6981 100644
--- a/actionpack/lib/action_dispatch/testing/integration.rb
+++ b/actionpack/lib/action_dispatch/testing/integration.rb
@@ -26,8 +26,8 @@ module ActionDispatch
# object's <tt>@response</tt> instance variable will point to the same
# response object.
#
- # You can also perform POST, PUT, DELETE, and HEAD requests with +#post+,
- # +#put+, +#delete+, and +#head+.
+ # You can also perform POST, PATCH, PUT, DELETE, and HEAD requests with
+ # +#post+, +#patch+, +#put+, +#delete+, and +#head+.
def get(path, parameters = nil, headers = nil)
process :get, path, parameters, headers
end
@@ -38,6 +38,12 @@ module ActionDispatch
process :post, path, parameters, headers
end
+ # Performs a PATCH request with the given parameters. See +#get+ for more
+ # details.
+ def patch(path, parameters = nil, headers = nil)
+ process :patch, path, parameters, headers
+ end
+
# Performs a PUT request with the given parameters. See +#get+ for more
# details.
def put(path, parameters = nil, headers = nil)
@@ -65,10 +71,10 @@ module ActionDispatch
# Performs an XMLHttpRequest request with the given parameters, mirroring
# a request from the Prototype library.
#
- # The request_method is +:get+, +:post+, +:put+, +:delete+ or +:head+; the
- # parameters are +nil+, a hash, or a url-encoded or multipart string;
- # the headers are a hash. Keys are automatically upcased and prefixed
- # with 'HTTP_' if not already.
+ # The request_method is +:get+, +:post+, +:patch+, +:put+, +:delete+ or
+ # +:head+; the parameters are +nil+, a hash, or a url-encoded or multipart
+ # string; the headers are a hash. Keys are automatically upcased and
+ # prefixed with 'HTTP_' if not already.
def xml_http_request(request_method, path, parameters = nil, headers = nil)
headers ||= {}
headers['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
@@ -108,6 +114,12 @@ module ActionDispatch
request_via_redirect(:post, path, parameters, headers)
end
+ # Performs a PATCH request, following any subsequent redirect.
+ # See +request_via_redirect+ for more information.
+ def patch_via_redirect(path, parameters = nil, headers = nil)
+ request_via_redirect(:patch, path, parameters, headers)
+ end
+
# Performs a PUT request, following any subsequent redirect.
# See +request_via_redirect+ for more information.
def put_via_redirect(path, parameters = nil, headers = nil)
@@ -318,7 +330,7 @@ module ActionDispatch
@integration_session = Integration::Session.new(app)
end
- %w(get post put head delete options cookies assigns
+ %w(get post patch put head delete options cookies assigns
xml_http_request xhr get_via_redirect post_via_redirect).each do |method|
define_method(method) do |*args|
reset! unless integration_session
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index cae345a1d6..53ae8b66da 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -250,7 +250,7 @@ module ActionView
#
# You can force the form to use the full array of HTTP verbs by setting
#
- # :method => (:get|:post|:put|:delete)
+ # :method => (:get|:post|:patch|:put|:delete)
#
# in the options hash. If the verb is not GET or POST, which are natively supported by HTML forms, the
# form will be set to POST and a hidden input called _method will carry the intended verb for the server
@@ -385,7 +385,7 @@ module ActionView
object = convert_to_model(object)
as = options[:as]
- action, method = object.respond_to?(:persisted?) && object.persisted? ? [:edit, :put] : [:new, :post]
+ action, method = object.respond_to?(:persisted?) && object.persisted? ? [:edit, :patch] : [:new, :post]
options[:html].reverse_merge!(
:class => as ? "#{action}_#{as}" : dom_class(object, action),
:id => as ? "#{action}_#{as}" : [options[:namespace], dom_id(object, action)].compact.join("_").presence,
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index 53fd189c39..2cf1c9055c 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -313,7 +313,7 @@ module ActionView
options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split)
end
- escape = options.key?("escape") ? options.delete("escape") : true
+ escape = options.delete("escape") { true }
content = ERB::Util.html_escape(content) if escape
content_tag :textarea, content.to_s.html_safe, { "name" => name, "id" => sanitize_to_id(name) }.update(options)
diff --git a/actionpack/lib/action_view/helpers/tags/base.rb b/actionpack/lib/action_view/helpers/tags/base.rb
index 1ece0ad2fc..d949ff5194 100644
--- a/actionpack/lib/action_view/helpers/tags/base.rb
+++ b/actionpack/lib/action_view/helpers/tags/base.rb
@@ -75,14 +75,14 @@ module ActionView
def add_default_name_and_id(options)
if options.has_key?("index")
- options["name"] ||= tag_name_with_index(options["index"])
+ options["name"] ||= options.fetch("name"){ tag_name_with_index(options["index"]) }
options["id"] = options.fetch("id"){ tag_id_with_index(options["index"]) }
options.delete("index")
elsif defined?(@auto_index)
- options["name"] ||= tag_name_with_index(@auto_index)
+ options["name"] ||= options.fetch("name"){ tag_name_with_index(@auto_index) }
options["id"] = options.fetch("id"){ tag_id_with_index(@auto_index) }
else
- options["name"] ||= options['multiple'] ? tag_name_multiple : tag_name
+ options["name"] ||= options.fetch("name"){ options['multiple'] ? tag_name_multiple : tag_name }
options["id"] = options.fetch("id"){ tag_id }
end
options["id"] = [options.delete('namespace'), options["id"]].compact.join("_").presence
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index b5fc882e31..8d7417809b 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -146,12 +146,12 @@ module ActionView
# create an HTML form and immediately submit the form for processing using
# the HTTP verb specified. Useful for having links perform a POST operation
# in dangerous actions like deleting a record (which search bots can follow
- # while spidering your site). Supported verbs are <tt>:post</tt>, <tt>:delete</tt> and <tt>:put</tt>.
+ # while spidering your site). Supported verbs are <tt>:post</tt>, <tt>:delete</tt>, <tt>:patch</tt>, and <tt>:put</tt>.
# Note that if the user has JavaScript disabled, the request will fall back
# to using GET. If <tt>:href => '#'</tt> is used and the user has JavaScript
# disabled clicking the link will have no effect. If you are relying on the
# POST behavior, you should check for it in your controller's action by using
- # the request object's methods for <tt>post?</tt>, <tt>delete?</tt> or <tt>put?</tt>.
+ # the request object's methods for <tt>post?</tt>, <tt>delete?</tt>, <tt>:patch</tt>, or <tt>put?</tt>.
# * <tt>:remote => true</tt> - This will allow the unobtrusive JavaScript
# driver to make an Ajax request to the URL in question instead of following
# the link. The drivers each provide mechanisms for listening for the
@@ -272,7 +272,7 @@ module ActionView
#
# There are a few special +html_options+:
# * <tt>:method</tt> - Symbol of HTTP verb. Supported verbs are <tt>:post</tt>, <tt>:get</tt>,
- # <tt>:delete</tt> and <tt>:put</tt>. By default it will be <tt>:post</tt>.
+ # <tt>:delete</tt>, <tt>:patch</tt>, and <tt>:put</tt>. By default it will be <tt>:post</tt>.
# * <tt>:disabled</tt> - If set to true, it will generate a disabled button.
# * <tt>:confirm</tt> - This will use the unobtrusive JavaScript driver to
# prompt with the question specified. If the user accepts, the link is
@@ -329,7 +329,7 @@ module ActionView
remote = html_options.delete('remote')
method = html_options.delete('method').to_s
- method_tag = %w{put delete}.include?(method) ? method_tag(method) : ""
+ method_tag = %w{patch put delete}.include?(method) ? method_tag(method) : ""
form_method = method == 'get' ? 'get' : 'post'
form_options = html_options.delete('form') || {}
diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb
index 90c4a2759a..b7945a23be 100644
--- a/actionpack/lib/action_view/lookup_context.rb
+++ b/actionpack/lib/action_view/lookup_context.rb
@@ -9,7 +9,7 @@ module ActionView
# generate a key, given to view paths, used in the resolver cache lookup. Since
# this key is generated just once during the request, it speeds up all cache accesses.
class LookupContext #:nodoc:
- attr_accessor :prefixes
+ attr_accessor :prefixes, :rendered_format
mattr_accessor :fallbacks
@@fallbacks = FallbackFileSystemResolver.instances
@@ -170,23 +170,15 @@ module ActionView
def initialize(view_paths, details = {}, prefixes = [])
@details, @details_key = {}, nil
- @frozen_formats, @skip_default_locale = false, false
+ @skip_default_locale = false
@cache = true
@prefixes = prefixes
+ @rendered_format = nil
self.view_paths = view_paths
initialize_details(details)
end
- # Freeze the current formats in the lookup context. By freezing them, you
- # that next template lookups are not going to modify the formats. The con
- # use this, to ensure that formats won't be further modified (as it does
- def freeze_formats(formats, unless_frozen=false) #:nodoc:
- return if unless_frozen && @frozen_formats
- self.formats = formats
- @frozen_formats = true
- end
-
# Override formats= to expand ["*/*"] values and automatically
# add :html as fallback to :js.
def formats=(values)
diff --git a/actionpack/lib/action_view/renderer/abstract_renderer.rb b/actionpack/lib/action_view/renderer/abstract_renderer.rb
index a588abcee3..52473cd222 100644
--- a/actionpack/lib/action_view/renderer/abstract_renderer.rb
+++ b/actionpack/lib/action_view/renderer/abstract_renderer.rb
@@ -1,7 +1,7 @@
module ActionView
class AbstractRenderer #:nodoc:
delegate :find_template, :template_exists?, :with_fallbacks, :update_details,
- :with_layout_format, :formats, :freeze_formats, :to => :@lookup_context
+ :with_layout_format, :formats, :to => :@lookup_context
def initialize(lookup_context)
@lookup_context = lookup_context
diff --git a/actionpack/lib/action_view/renderer/template_renderer.rb b/actionpack/lib/action_view/renderer/template_renderer.rb
index f3abc6d533..20f75fba45 100644
--- a/actionpack/lib/action_view/renderer/template_renderer.rb
+++ b/actionpack/lib/action_view/renderer/template_renderer.rb
@@ -6,7 +6,8 @@ module ActionView
@view = context
@details = extract_details(options)
template = determine_template(options)
- freeze_formats(template.formats, true)
+ @lookup_context.rendered_format ||= template.formats.first
+ @lookup_context.formats = template.formats
render_template(template, options[:layout], options[:locals])
end
diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb
index 644debd49c..edb3d427d5 100644
--- a/actionpack/lib/action_view/template.rb
+++ b/actionpack/lib/action_view/template.rb
@@ -163,7 +163,6 @@ module ActionView
pieces = @virtual_path.split("/")
name = pieces.pop
partial = !!name.sub!(/^_/, "")
- lookup.formats = @formats
lookup.disable_cache do
lookup.find_template(name, [ pieces.join('/') ], partial, @locals)
end
diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb
index 323df67c97..19b9112afd 100644
--- a/actionpack/lib/action_view/template/handlers/erb.rb
+++ b/actionpack/lib/action_view/template/handlers/erb.rb
@@ -44,10 +44,6 @@ module ActionView
class_attribute :erb_trim_mode
self.erb_trim_mode = '-'
- # Default format used by ERB.
- class_attribute :default_format
- self.default_format = Mime::HTML
-
# Default implementation used.
class_attribute :erb_implementation
self.erb_implementation = Erubis