diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/routing')
-rw-r--r-- | actionpack/lib/action_dispatch/routing/mapper.rb | 57 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/redirection.rb | 6 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/route_set.rb | 38 |
3 files changed, 57 insertions, 44 deletions
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 64352d5742..1264e7e00b 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -16,7 +16,10 @@ module ActionDispatch class Constraints < Endpoint #:nodoc: attr_reader :app, :constraints - def initialize(app, constraints, dispatcher_p) + SERVE = ->(app, req) { app.serve req } + CALL = ->(app, req) { app.call req.env } + + def initialize(app, constraints, strategy) # Unwrap Constraints objects. I don't actually think it's possible # to pass a Constraints object to this constructor, but there were # multiple places that kept testing children of this object. I @@ -26,12 +29,12 @@ module ActionDispatch app = app.app end - @dispatcher = dispatcher_p + @strategy = strategy @app, @constraints, = app, constraints end - def dispatcher?; @dispatcher; end + def dispatcher?; @strategy == SERVE; end def matches?(req) @constraints.all? do |constraint| @@ -43,11 +46,7 @@ module ActionDispatch def serve(req) return [ 404, {'X-Cascade' => 'pass'}, [] ] unless matches?(req) - if dispatcher? - @app.serve req - else - @app.call req.env - end + @strategy.call @app, req end private @@ -241,11 +240,11 @@ module ActionDispatch def app(blocks) if to.respond_to?(:call) - Constraints.new(to, blocks, false) + Constraints.new(to, blocks, Constraints::CALL) elsif blocks.any? - Constraints.new(dispatcher(defaults), blocks, true) + Constraints.new(dispatcher(defaults.key?(:controller)), blocks, Constraints::SERVE) else - dispatcher(defaults) + dispatcher(defaults.key?(:controller)) end end @@ -1107,7 +1106,7 @@ module ActionDispatch end def resource_scope - { :controller => controller } + controller end alias :collection_scope :path @@ -1398,7 +1397,7 @@ module ActionDispatch end with_scope_level(:collection) do - scope(parent_resource.collection_scope) do + path_scope(parent_resource.collection_scope) do yield end end @@ -1424,7 +1423,7 @@ module ActionDispatch if shallow? shallow_scope(parent_resource.member_scope) { yield } else - scope(parent_resource.member_scope) { yield } + path_scope(parent_resource.member_scope) { yield } end end end @@ -1435,7 +1434,7 @@ module ActionDispatch end with_scope_level(:new) do - scope(parent_resource.new_scope(action_path(:new))) do + path_scope(parent_resource.new_scope(action_path(:new))) do yield end end @@ -1465,9 +1464,10 @@ module ActionDispatch end def shallow - scope(:shallow => true) do - yield - end + @scope = @scope.new(shallow: true) + yield + ensure + @scope = @scope.parent end def shallow? @@ -1684,7 +1684,7 @@ module ActionDispatch @nesting.push(resource) with_scope_level(kind) do - scope(parent_resource.resource_scope) { yield } + controller_scope(parent_resource.resource_scope) { yield } end ensure @nesting.pop @@ -1796,6 +1796,21 @@ module ActionDispatch def api_only? @set.api_only? end + private + + def controller_scope(controller) + @scope = @scope.new(controller: controller) + yield + ensure + @scope = @scope.parent + end + + def path_scope(path) + @scope = @scope.new(path: merge_path_scope(@scope[:path], path)) + yield + ensure + @scope = @scope.parent + end end # Routing Concerns allow you to declare common routes that can be reused @@ -1971,10 +1986,6 @@ module ActionDispatch def [](key) @hash.fetch(key) { @parent[key] } end - - def []=(k,v) - @hash[k] = v - end end def initialize(set) #:nodoc: diff --git a/actionpack/lib/action_dispatch/routing/redirection.rb b/actionpack/lib/action_dispatch/routing/redirection.rb index 3c1c4fadf6..d6987f4d09 100644 --- a/actionpack/lib/action_dispatch/routing/redirection.rb +++ b/actionpack/lib/action_dispatch/routing/redirection.rb @@ -24,7 +24,7 @@ module ActionDispatch def serve(req) req.check_path_parameters! uri = URI.parse(path(req.path_parameters, req)) - + unless uri.host if relative_path?(uri.path) uri.path = "#{req.script_name}/#{uri.path}" @@ -32,7 +32,7 @@ module ActionDispatch uri.path = req.script_name.empty? ? "/" : req.script_name end end - + uri.scheme ||= req.scheme uri.host ||= req.host uri.port ||= req.port unless req.standard_port? @@ -124,7 +124,7 @@ module ActionDispatch url_options[:script_name] = request.script_name end end - + ActionDispatch::Http::URL.url_for url_options end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index f3d7a234d7..c97c8ba0f0 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -21,8 +21,8 @@ module ActionDispatch alias inspect to_s class Dispatcher < Routing::Endpoint - def initialize(defaults) - @defaults = defaults + def initialize(raise_on_name_error) + @raise_on_name_error = raise_on_name_error @controller_class_names = ThreadSafe::Cache.new end @@ -35,11 +35,11 @@ module ActionDispatch prepare_params!(params) # Just raise undefined constant errors if a controller was specified as default. - unless controller = controller(params, @defaults.key?(:controller)) + controller = controller(params, @raise_on_name_error) do return [404, {'X-Cascade' => 'pass'}, []] end - dispatch(controller, params[:action], req.env) + dispatch(controller, params[:action], req) end def prepare_params!(params) @@ -53,24 +53,25 @@ module ActionDispatch # segment, as in :controller(/:action), we should simply return nil and # delegate the control back to Rack cascade. Besides, if this is not a default # controller, it means we should respect the @scope[:module] parameter. - def controller(params, default_controller=true) - if params && params.key?(:controller) - controller_param = params[:controller] - controller_reference(controller_param) - end + def controller(params, raise_on_name_error=true) + controller_reference params.fetch(:controller) { yield } rescue NameError => e - raise ActionController::RoutingError, e.message, e.backtrace if default_controller + raise ActionController::RoutingError, e.message, e.backtrace if raise_on_name_error end - private + protected + + attr_reader :controller_class_names def controller_reference(controller_param) - const_name = @controller_class_names[controller_param] ||= "#{controller_param.camelize}Controller" + const_name = controller_class_names[controller_param] ||= "#{controller_param.camelize}Controller" ActiveSupport::Dependencies.constantize(const_name) end - def dispatch(controller, action, env) - controller.action(action).call(env) + private + + def dispatch(controller, action, req) + controller.action(action).call(req.env) end def normalize_controller!(params) @@ -267,7 +268,7 @@ module ActionDispatch path_params -= controller_options.keys path_params -= result.keys end - inner_options.each do |key, _| + inner_options.each_key do |key| path_params.delete(key) end @@ -313,7 +314,7 @@ module ActionDispatch attr_accessor :formatter, :set, :named_routes, :default_scope, :router attr_accessor :disable_clear_and_finalize, :resources_path_names - attr_accessor :default_url_options + attr_accessor :default_url_options, :dispatcher_class attr_reader :env_key alias :routes :set @@ -356,6 +357,7 @@ module ActionDispatch @set = Journey::Routes.new @router = Journey::Router.new @set @formatter = Journey::Formatter.new @set + @dispatcher_class = Routing::RouteSet::Dispatcher end def relative_url_root @@ -413,8 +415,8 @@ module ActionDispatch @prepend.each { |blk| eval_block(blk) } end - def dispatcher(defaults) - Routing::RouteSet::Dispatcher.new(defaults) + def dispatcher(raise_on_name_error) + dispatcher_class.new(raise_on_name_error) end module MountedHelpers |