aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib')
-rw-r--r--actionpack/lib/abstract_controller/helpers.rb28
-rw-r--r--actionpack/lib/action_controller/metal/flash.rb17
-rw-r--r--actionpack/lib/action_dispatch/http/request.rb2
-rw-r--r--actionpack/lib/action_dispatch/journey/formatter.rb6
-rw-r--r--actionpack/lib/action_dispatch/journey/route.rb12
-rw-r--r--actionpack/lib/action_dispatch/middleware/params_parser.rb2
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb27
7 files changed, 80 insertions, 14 deletions
diff --git a/actionpack/lib/abstract_controller/helpers.rb b/actionpack/lib/abstract_controller/helpers.rb
index 5ae8c6c3b0..e77e4e01e9 100644
--- a/actionpack/lib/abstract_controller/helpers.rb
+++ b/actionpack/lib/abstract_controller/helpers.rb
@@ -12,7 +12,24 @@ module AbstractController
self._helper_methods = Array.new
end
+ class MissingHelperError < LoadError
+ def initialize(error, path)
+ @error = error
+ @path = "helpers/#{path}.rb"
+ set_backtrace error.backtrace
+
+ if error.path =~ /^#{path}(\.rb)?$/
+ super("Missing helper file helpers/%s.rb" % path)
+ else
+ raise error
+ end
+ end
+ end
+
module ClassMethods
+ MissingHelperError = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('AbstractController::Helpers::ClassMethods::MissingHelperError',
+ 'AbstractController::Helpers::MissingHelperError')
+
# When a class is inherited, wrap its helper module in a new module.
# This ensures that the parent class's module can be changed
# independently of the child class's.
@@ -134,7 +151,7 @@ module AbstractController
begin
require_dependency(file_name)
rescue LoadError => e
- raise MissingHelperError.new(e, file_name)
+ raise AbstractController::Helpers::MissingHelperError.new(e, file_name)
end
file_name.camelize.constantize
when Module
@@ -145,15 +162,6 @@ module AbstractController
end
end
- class MissingHelperError < LoadError
- def initialize(error, path)
- @error = error
- @path = "helpers/#{path}.rb"
- set_backtrace error.backtrace
- super("Missing helper file helpers/%s.rb" % path)
- end
- end
-
private
# Makes all the (instance) methods in the helper module available to templates
# rendered through this controller.
diff --git a/actionpack/lib/action_controller/metal/flash.rb b/actionpack/lib/action_controller/metal/flash.rb
index b078beb675..1d77e331f8 100644
--- a/actionpack/lib/action_controller/metal/flash.rb
+++ b/actionpack/lib/action_controller/metal/flash.rb
@@ -11,6 +11,23 @@ module ActionController #:nodoc:
end
module ClassMethods
+ # Creates new flash types. You can pass as many types as you want to create
+ # flash types other than the default <tt>alert</tt> and <tt>notice</tt> in
+ # your controllers and views. For instance:
+ #
+ # # in application_controller.rb
+ # class ApplicationController < ActionController::Base
+ # add_flash_types :warning
+ # end
+ #
+ # # in your controller
+ # redirect_to user_path(@user), warning: "Incomplete profile"
+ #
+ # # in your view
+ # <%= warning %>
+ #
+ # This method will automatically define a new method for each of the given
+ # names, and it will be available in your views.
def add_flash_types(*types)
types.each do |type|
next if _flash_types.include?(type)
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index 4ca1d35489..b4cf8ad2f7 100644
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -226,7 +226,7 @@ module ActionDispatch
def raw_post
unless @env.include? 'RAW_POST_DATA'
raw_post_body = body
- @env['RAW_POST_DATA'] = raw_post_body.read(@env['CONTENT_LENGTH'].to_i)
+ @env['RAW_POST_DATA'] = raw_post_body.read(content_length)
raw_post_body.rewind if raw_post_body.respond_to?(:rewind)
end
@env['RAW_POST_DATA']
diff --git a/actionpack/lib/action_dispatch/journey/formatter.rb b/actionpack/lib/action_dispatch/journey/formatter.rb
index e288f026c7..7764763791 100644
--- a/actionpack/lib/action_dispatch/journey/formatter.rb
+++ b/actionpack/lib/action_dispatch/journey/formatter.rb
@@ -18,7 +18,11 @@ module ActionDispatch
match_route(name, constraints) do |route|
parameterized_parts = extract_parameterized_parts(route, options, recall, parameterize)
- next if !name && route.requirements.empty? && route.parts.empty?
+
+ # Skip this route unless a name has been provided or it is a
+ # standard Rails route since we can't determine whether an options
+ # hash passed to url_for matches a Rack application or a redirect.
+ next unless name || route.dispatcher?
missing_keys = missing_keys(route, parameterized_parts)
next unless missing_keys.empty?
diff --git a/actionpack/lib/action_dispatch/journey/route.rb b/actionpack/lib/action_dispatch/journey/route.rb
index 50e1853094..c8eb0f6f2d 100644
--- a/actionpack/lib/action_dispatch/journey/route.rb
+++ b/actionpack/lib/action_dispatch/journey/route.rb
@@ -16,6 +16,14 @@ module ActionDispatch
@app = app
@path = path
+ # Unwrap any constraints so we can see what's inside for route generation.
+ # This allows the formatter to skip over any mounted applications or redirects
+ # that shouldn't be matched when using a url_for without a route name.
+ while app.is_a?(Routing::Mapper::Constraints) do
+ app = app.app
+ end
+ @dispatcher = app.is_a?(Routing::RouteSet::Dispatcher)
+
@constraints = constraints
@defaults = defaults
@required_defaults = nil
@@ -93,6 +101,10 @@ module ActionDispatch
end
end
+ def dispatcher?
+ @dispatcher
+ end
+
def matches?(request)
constraints.all? do |method, value|
next true unless request.respond_to?(method)
diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb
index fb70b60ef6..b426183488 100644
--- a/actionpack/lib/action_dispatch/middleware/params_parser.rb
+++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb
@@ -41,7 +41,7 @@ module ActionDispatch
when Proc
strategy.call(request.raw_post)
when :json
- data = ActiveSupport::JSON.decode(request.body)
+ data = ActiveSupport::JSON.decode(request.raw_post)
data = {:_json => data} unless data.is_a?(Hash)
Request::Utils.deep_munge(data).with_indifferent_access
else
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 3ae9f92c0b..0e5dc1fc6c 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -186,10 +186,16 @@ module ActionDispatch
klass = Journey::Router::Utils
@path_parts.zip(args) do |part, arg|
+ parameterized_arg = arg.to_param
+
+ if parameterized_arg.nil? || parameterized_arg.empty?
+ raise_generation_error(args)
+ end
+
# Replace each route parameter
# e.g. :id for regular parameter or *path for globbing
# with ruby string interpolation code
- path.gsub!(/(\*|:)#{part}/, klass.escape_fragment(arg.to_param))
+ path.gsub!(/(\*|:)#{part}/, klass.escape_fragment(parameterized_arg))
end
path
end
@@ -197,6 +203,25 @@ module ActionDispatch
def optimize_routes_generation?(t)
t.send(:optimize_routes_generation?)
end
+
+ def raise_generation_error(args)
+ parts, missing_keys = [], []
+
+ @path_parts.zip(args) do |part, arg|
+ parameterized_arg = arg.to_param
+
+ if parameterized_arg.nil? || parameterized_arg.empty?
+ missing_keys << part
+ end
+
+ parts << [part, arg]
+ end
+
+ message = "No route matches #{Hash[parts].inspect}"
+ message << " missing required keys: #{missing_keys.inspect}"
+
+ raise ActionController::UrlGenerationError, message
+ end
end
def initialize(route, options)