class ActionDispatch::Routing::Mapper::Mapping
:nodoc:
def app
def app Constraints.new(endpoint, blocks, @set.request_class) end
def blocks
def blocks if options[:constraints].present? && !options[:constraints].is_a?(Hash) [options[:constraints]] else scope[:blocks] || [] end end
def constraints
def constraints @constraints ||= {}.tap do |constraints| constraints.merge!(scope[:constraints]) if scope[:constraints] options.except(*IGNORE_OPTIONS).each do |key, option| constraints[key] = option if Regexp === option end constraints.merge!(options[:constraints]) if options[:constraints].is_a?(Hash) end end
def default_action
def default_action options[:action] || scope[:action] end
def default_controller
def default_controller options[:controller] || scope[:controller] end
def default_controller_and_action
def default_controller_and_action if to.respond_to?(:call) { } else if to.is_a?(String) controller, action = to.split('#') elsif to.is_a?(Symbol) action = to.to_s end controller ||= default_controller action ||= default_action if @scope[:module] && !controller.is_a?(Regexp) if controller =~ %r{\A/} controller = controller[1..-1] else controller = [@scope[:module], controller].compact.join("/").presence end end if controller.is_a?(String) && controller =~ %r{\A/} raise ArgumentError, "controller name should not start with a slash" end controller = controller.to_s unless controller.is_a?(Regexp) action = action.to_s unless action.is_a?(Regexp) if controller.blank? && segment_keys.exclude?(:controller) message = "Missing :controller key on routes definition, please check your routes." raise ArgumentError, message end if action.blank? && segment_keys.exclude?(:action) message = "Missing :action key on routes definition, please check your routes." raise ArgumentError, message end if controller.is_a?(String) && controller !~ /\A[a-z_0-9\/]*\z/ message = "'#{controller}' is not a supported controller name. This can lead to potential routing problems." message << " See http://guides.rubyonrails.org/routing.html#specifying-a-controller-to-use" raise ArgumentError, message end hash = {} hash[:controller] = controller unless controller.blank? hash[:action] = action unless action.blank? hash end end
def dispatcher
def dispatcher Routing::RouteSet::Dispatcher.new(:defaults => defaults) end
def endpoint
def endpoint to.respond_to?(:call) ? to : dispatcher end
def initialize(set, scope, path, options)
def initialize(set, scope, path, options) @set, @scope, @path, @options = set, scope, path, options @requirements, @conditions, @defaults = {}, {}, {} normalize_options! normalize_path! normalize_requirements! normalize_conditions! normalize_defaults! end
def normalize_conditions!
def normalize_conditions! @conditions[:path_info] = path constraints.each do |key, condition| unless segment_keys.include?(key) || key == :controller @conditions[key] = condition end end required_defaults = [] options.each do |key, required_default| unless segment_keys.include?(key) || IGNORE_OPTIONS.include?(key) || Regexp === required_default required_defaults << key end end @conditions[:required_defaults] = required_defaults via_all = options.delete(:via) if options[:via] == :all if !via_all && options[:via].blank? msg = "You should not use the `match` method in your router without specifying an HTTP method.\n" \ "If you want to expose your action to both GET and POST, add `via: [:get, :post]` option.\n" \ "If you want to expose your action to GET, use `get` in the router:\n" \ " Instead of: match \"controller#action\"\n" \ " Do: get \"controller#action\"" raise msg end if via = options[:via] @conditions[:request_method] = Array(via).map { |m| m.to_s.dasherize.upcase } end end
def normalize_defaults!
def normalize_defaults! @defaults.merge!(scope[:defaults]) if scope[:defaults] @defaults.merge!(options[:defaults]) if options[:defaults] options.each do |key, default| unless Regexp === default || IGNORE_OPTIONS.include?(key) @defaults[key] = default end end if options[:constraints].is_a?(Hash) options[:constraints].each do |key, default| if URL_OPTIONS.include?(key) && (String === default || Fixnum === default) @defaults[key] ||= default end end end if Regexp === options[:format] @defaults[:format] = nil elsif String === options[:format] @defaults[:format] = options[:format] end end
def normalize_options!
def normalize_options! @options.reverse_merge!(scope[:options]) if scope[:options] path_without_format = path.sub(/\(\.:format\)$/, '') # Add a constraint for wildcard route to make it non-greedy and match the # optional format part of the route by default if path_without_format.match(WILDCARD_PATH) && @options[:format] != false @options[$1.to_sym] ||= /.+?/ end if path_without_format.match(':controller') raise ArgumentError, ":controller segment is not allowed within a namespace block" if scope[:module] # Add a default constraint for :controller path segments that matches namespaced # controllers with default routes like :controller/:action/:id(.:format), e.g: # GET /admin/products/show/1 # => { controller: 'admin/products', action: 'show', id: '1' } @options[:controller] ||= /.+?/ end @options.merge!(default_controller_and_action) end
def normalize_path!
def normalize_path! raise ArgumentError, "path is required" if @path.blank? @path = Mapper.normalize_path(@path) if required_format? @path = "#{@path}.:format" elsif optional_format? @path = "#{@path}(.:format)" end end
def normalize_requirements!
def normalize_requirements! constraints.each do |key, requirement| next unless segment_keys.include?(key) || key == :controller verify_regexp_requirement(requirement) if requirement.is_a?(Regexp) @requirements[key] = requirement end if options[:format] == true @requirements[:format] ||= /.+/ elsif Regexp === options[:format] @requirements[:format] = options[:format] elsif String === options[:format] @requirements[:format] = Regexp.compile(options[:format]) end end
def optional_format?
def optional_format? options[:format] != false && !path.include?(':format') && !path.end_with?('/') end
def path_pattern
def path_pattern Journey::Path::Pattern.new(strexp) end
def required_format?
def required_format? options[:format] == true end
def segment_keys
def segment_keys @segment_keys ||= path_pattern.names.map{ |s| s.to_sym } end
def strexp
def strexp Journey::Router::Strexp.compile(path, requirements, SEPARATORS) end
def to
def to options[:to] end
def to_route
def to_route [ app, conditions, requirements, defaults, options[:as], options[:anchor] ] end
def verify_regexp_requirement(requirement)
def verify_regexp_requirement(requirement) if requirement.source =~ ANCHOR_CHARACTERS_REGEX raise ArgumentError, "Regexp anchor characters are not allowed in routing requirements: #{requirement.inspect}" end if requirement.multiline? raise ArgumentError, "Regexp multiline option is not allowed in routing requirements: #{requirement.inspect}" end end