diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/routing/mapper.rb')
-rw-r--r-- | actionpack/lib/action_dispatch/routing/mapper.rb | 205 |
1 files changed, 96 insertions, 109 deletions
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 388f695187..0b4ba8c9f5 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -131,6 +131,7 @@ module ActionDispatch end defaults[:controller] ||= default_controller + defaults[:action] ||= default_action defaults.delete(:controller) if defaults[:controller].blank? defaults.delete(:action) if defaults[:action].blank? @@ -187,6 +188,12 @@ module ActionDispatch @scope[:controller].to_s end end + + def default_action + if @options[:action] + @options[:action].to_s + end + end end # Invokes Rack::Mount::Utils.normalize path and ensure that @@ -433,10 +440,14 @@ module ActionDispatch end module Resources + # CANONICAL_ACTIONS holds all actions that does not need a prefix or + # a path appended since they fit properly in their scope level. + VALID_ON_OPTIONS = [:new, :collection, :member] + CANONICAL_ACTIONS = [:index, :create, :new, :show, :update, :destroy] + MERGE_FROM_SCOPE_OPTIONS = [:shallow, :constraints] + class Resource #:nodoc: - def self.default_actions - [:index, :create, :new, :show, :update, :destroy, :edit] - end + DEFAULT_ACTIONS = [:index, :create, :new, :show, :update, :destroy, :edit] attr_reader :controller, :path, :options @@ -449,7 +460,7 @@ module ActionDispatch end def default_actions - self.class.default_actions + self.class::DEFAULT_ACTIONS end def actions @@ -533,8 +544,8 @@ module ActionDispatch ["#{path}/:id", options] end - def new_scope - [path] + def new_scope(new_path) + ["#{path}/#{new_path}"] end def nested_scope @@ -543,9 +554,7 @@ module ActionDispatch end class SingletonResource < Resource #:nodoc: - def self.default_actions - [:show, :create, :update, :destroy, :new, :edit] - end + DEFAULT_ACTIONS = [:show, :create, :update, :destroy, :new, :edit] def initialize(entities, options) @name = entities.to_s @@ -591,8 +600,6 @@ module ActionDispatch def resource(*resources, &block) options = resources.extract_options! - options = (@scope[:options] || {}).merge(options) - options[:shallow] = true if @scope[:shallow] && !options.has_key?(:shallow) if apply_common_behavior_for(:resource, resources, options, &block) return self @@ -602,9 +609,12 @@ module ActionDispatch yield if block_given? collection_scope do - post :create if parent_resource.actions.include?(:create) - get :new if parent_resource.actions.include?(:new) - end + post :create + end if parent_resource.actions.include?(:create) + + new_scope do + get :new + end if parent_resource.actions.include?(:new) member_scope do get :show if parent_resource.actions.include?(:show) @@ -619,8 +629,6 @@ module ActionDispatch def resources(*resources, &block) options = resources.extract_options! - options = (@scope[:options] || {}).merge(options) - options[:shallow] = true if @scope[:shallow] && !options.has_key?(:shallow) if apply_common_behavior_for(:resources, resources, options, &block) return self @@ -632,9 +640,12 @@ module ActionDispatch collection_scope do get :index if parent_resource.actions.include?(:index) post :create if parent_resource.actions.include?(:create) - get :new if parent_resource.actions.include?(:new) end + new_scope do + get :new + end if parent_resource.actions.include?(:new) + member_scope do get :show if parent_resource.actions.include?(:show) put :update if parent_resource.actions.include?(:update) @@ -671,12 +682,8 @@ module ActionDispatch raise ArgumentError, "can't use new outside resource(s) scope" end - with_scope_level(:new) do - scope(*parent_resource.new_scope) do - scope(action_path(:new)) do - yield - end - end + new_scope do + yield end end @@ -717,8 +724,7 @@ module ActionDispatch end def match(*args) - options = args.extract_options! - + options = args.extract_options!.dup options[:anchor] = true unless options.key?(:anchor) if args.length > 1 @@ -726,17 +732,12 @@ module ActionDispatch return self end - if [:collection, :member, :new].include?(options[:on]) + on = options.delete(:on) + if VALID_ON_OPTIONS.include?(on) args.push(options) - - case options.delete(:on) - when :collection - return collection { match(*args) } - when :member - return member { match(*args) } - when :new - return new { match(*args) } - end + return send(on){ match(*args) } + elsif on + raise ArgumentError, "Unknown scope #{on.inspect} given to :on" end if @scope[:scope_level] == :resource @@ -745,10 +746,12 @@ module ActionDispatch end path = options.delete(:path) + action = args.first - if args.first.is_a?(Symbol) - path = path_for_action(args.first, path) - options = options_for_action(args.first, options) + if action.is_a?(Symbol) + path = path_for_action(action, path) + options[:to] ||= action + options[:as] = name_for_action(action, options[:as]) with_exclusive_scope do return super(path, options) @@ -786,11 +789,11 @@ module ActionDispatch end protected + def parent_resource #:nodoc: @scope[:scope_level_resource] end - private def apply_common_behavior_for(method, resources, options, &block) if resources.length > 1 resources.each { |r| send(method, r, options, &block) } @@ -804,6 +807,10 @@ module ActionDispatch return true end + scope_options = @scope.slice(*MERGE_FROM_SCOPE_OPTIONS).delete_if{ |k,v| v.blank? } + options.reverse_merge!(scope_options) unless scope_options.empty? + options.reverse_merge!(@scope[:options]) unless @scope[:options].blank? + if resource_scope? nested do send(method, resources.pop, options, &block) @@ -852,6 +859,14 @@ module ActionDispatch end end + def new_scope + with_scope_level(:new) do + scope(*parent_resource.new_scope(action_path(:new))) do + yield + end + end + end + def collection_scope with_scope_level(:collection) do scope(*parent_resource.collection_scope) do @@ -868,48 +883,30 @@ module ActionDispatch end end + def canonical_action?(action, flag) + flag && CANONICAL_ACTIONS.include?(action) + end + + def shallow_scoping? + parent_resource && parent_resource.shallow? && @scope[:scope_level] == :member + end + def path_for_action(action, path) - case action - when :index, :create - "#{@scope[:path]}(.:format)" - when :show, :update, :destroy - if parent_resource.shallow? - "#{@scope[:shallow_path]}/#{parent_resource.path}/:id(.:format)" - else - "#{@scope[:path]}(.:format)" - end - when :new - "#{@scope[:path]}/#{action_path(:new)}(.:format)" - when :edit - if parent_resource.shallow? - "#{@scope[:shallow_path]}/#{parent_resource.path}/:id/#{action_path(:edit)}(.:format)" - else - "#{@scope[:path]}/#{action_path(:edit)}(.:format)" - end + prefix = shallow_scoping? ? + "#{@scope[:shallow_path]}/#{parent_resource.path}/:id" : @scope[:path] + + if canonical_action?(action, path.blank?) + "#{prefix}(.:format)" else - case @scope[:scope_level] - when :collection, :new - "#{@scope[:path]}/#{action_path(action, path)}(.:format)" - else - if parent_resource.shallow? - "#{@scope[:shallow_path]}/#{parent_resource.path}/:id/#{action_path(action, path)}(.:format)" - else - "#{@scope[:path]}/#{action_path(action, path)}(.:format)" - end - end + "#{prefix}/#{action_path(action, path)}(.:format)" end end def path_for_custom_action - case @scope[:scope_level] - when :collection, :new - @scope[:path] + if shallow_scoping? + "#{@scope[:shallow_path]}/#{parent_resource.path}/:id" else - if parent_resource.shallow? - "#{@scope[:shallow_path]}/#{parent_resource.path}/:id" - else - @scope[:path] - end + @scope[:path] end end @@ -917,50 +914,40 @@ module ActionDispatch path || @scope[:path_names][name.to_sym] || name.to_s end - def options_for_action(action, options) - options.reverse_merge( - :to => action, - :as => name_for_action(action) - ) + def prefix_name_for_action(action, as) + if as.present? + "#{as}_" + elsif as + "" + elsif !canonical_action?(action, @scope[:scope_level]) + "#{action}_" + end end - def name_for_action(action) - name_prefix = @scope[:as].blank? ? "" : "#{@scope[:as]}_" - shallow_prefix = @scope[:shallow_prefix].blank? ? "" : "#{@scope[:shallow_prefix]}_" + def name_for_action(action, as=nil) + prefix = prefix_name_for_action(action, as) + name_prefix = @scope[:as] - case action - when :index, :create - "#{name_prefix}#{parent_resource.collection_name}" - when :show, :update, :destroy - if parent_resource.shallow? - "#{shallow_prefix}#{parent_resource.member_name}" - else - "#{name_prefix}#{parent_resource.member_name}" - end - when :edit - if parent_resource.shallow? - "edit_#{shallow_prefix}#{parent_resource.member_name}" - else - "edit_#{name_prefix}#{parent_resource.member_name}" - end + if parent_resource + collection_name = parent_resource.collection_name + member_name = parent_resource.member_name + name_prefix = "#{name_prefix}_" if name_prefix.present? + end + + case @scope[:scope_level] + when :collection + "#{prefix}#{name_prefix}#{collection_name}" when :new - "new_#{name_prefix}#{parent_resource.member_name}" + "#{prefix}new_#{name_prefix}#{member_name}" else - case @scope[:scope_level] - when :collection - "#{action}_#{name_prefix}#{parent_resource.collection_name}" - when :new - "#{action}_new_#{name_prefix}#{parent_resource.member_name}" + if shallow_scoping? + shallow_prefix = "#{@scope[:shallow_prefix]}_" if @scope[:shallow_prefix].present? + "#{prefix}#{shallow_prefix}#{member_name}" else - if parent_resource.shallow? - "#{action}_#{shallow_prefix}#{parent_resource.member_name}" - else - "#{action}_#{name_prefix}#{parent_resource.member_name}" - end + "#{prefix}#{name_prefix}#{member_name}" end end end - end include Base |