Class: Rack::Mount::RouteSet

### Home Classes Methods

### In Files

- lib/rack/mount/route_set.rb

### Parent

Object

### Methods

- ::new
- ::new_without_optimizations
- #add_route
- #call
- #freeze
- #length
- #recognition_stats
- #recognize
- #url

### Files

- LICENSE
- README.rdoc

### Class/Module Index

Quicksearch

- Rack
- Rack::Mount
- Rack::Mount::Analysis
- Rack::Mount::Analysis::Splitting
- Rack::Mount::Analysis::Splitting::Key
- Rack::Mount::GeneratableRegexp
- Rack::Mount::GeneratableRegexp::InstanceMethods
- Rack::Mount::RegexpWithNamedGroups
- Rack::Mount::Route
- Rack::Mount::RouteSet
- Rack::Mount::RoutingError
- Rack::Mount::Strexp
- Rack::Mount::StrexpParser
- Rack::Mount::StrexpParser::ScanError
- Rack::Mount::Utils
- Regin
- Regin::Alternation
- Regin::Anchor
- Regin::Atom
- Regin::Character
- Regin::CharacterClass
- Regin::Collection
- Regin::Expression
- Regin::Group
- Regin::Options
- Regin::Parser
- Regin::Parser::ScanError
- Multimap
- Multiset
- NestedMultimap

No matching classes.

# Rack::Mount::RouteSet

### Constants

PASS
PATH_INFO
X_CASCADE

### Public Class Methods

new(options = {}, &block) click to toggle source

Basic RouteSet initializer.

If a block is given, the set is yielded and finalized.

See other aspects for other valid options:

- `Generation::RouteSet.new`

- `Recognition::RouteSet.new`

    # File lib/rack/mount/route_set.rb, line 21
    def initialize(options = {}, &block)
      @parameters_key = options.delete(:parameters_key) || 'rack.routing_args'
      @parameters_key.freeze

      @named_routes = {}

      @recognition_key_analyzer = Analysis::Splitting.new
      @generation_key_analyzer  = Analysis::Frequency.new

      @request_class = options.delete(:request_class) || Rack::Request
      @valid_conditions = @request_class.public_instance_methods.map! { |m| m.to_sym }

      extend CodeGeneration unless options[:_optimize] == false
      @optimized_recognize_defined = false

      @routes = []
      expire!

      if block_given?
        yield self
        rehash
      end
    end

new_without_optimizations(options = {}, &block) click to toggle source

Initialize a new RouteSet without optimizations

    # File lib/rack/mount/route_set.rb, line 10
    def self.new_without_optimizations(options = {}, &block)
      new(options.merge(:_optimize => false), &block)
    end

### Public Instance Methods

add_route(app, conditions = {}, defaults = {}, name = nil) click to toggle source

Builder method to add a route to the set

`app` | A valid Rack app to call if the conditions are met.
`conditions` | A hash of conditions to match against. Conditions may be expressed as strings or regexps to match against.
`defaults` | A hash of values that always gets merged in
`name` | Symbol identifier for the route used with named route generations

    # File lib/rack/mount/route_set.rb, line 54
    def add_route(app, conditions = {}, defaults = {}, name = nil)
      unless conditions.is_a?(Hash)
        raise ArgumentError, 'conditions must be a Hash'
      end

      unless conditions.all? { |method, pattern|
          @valid_conditions.include?(method)
        }
        raise ArgumentError, 'conditions may only include ' +
          @valid_conditions.inspect
      end

      route = Route.new(app, conditions, defaults, name)
      @routes << route

      @recognition_key_analyzer << route.conditions

      @named_routes[route.name] = route if route.name
      @generation_key_analyzer << route.generation_keys

      expire!
      route
    end

call(env) click to toggle source

Rack compatible recognition and dispatching method. Routes are tried until one returns a non-catch status code. If no routes match, the catch status code is returned.

This method can only be invoked after the RouteSet has been finalized.

    # File lib/rack/mount/route_set.rb, line 132
    def call(env)
      raise 'route set not finalized' unless @recognition_graph

      env[PATH_INFO] = Utils.normalize_path(env[PATH_INFO])

      request = nil
      req = @request_class.new(env)
      recognize(req) do |route, matches, params|
        # TODO: We only want to unescape params from uri related methods
        params.each { |k, v| params[k] = Utils.unescape_uri(v) if v.is_a?(String) }

        if route.prefix?
          env[Prefix::KEY] = matches[:path_info].to_s
        end

        env[@parameters_key] = params
        result = route.app.call(env)
        return result unless result[1][X_CASCADE] == PASS
      end

      request || [404, {'Content-Type' => 'text/html', 'X-Cascade' => 'pass'}, ['Not Found']]
    end

freeze() click to toggle source

Finalizes the set and builds optimized data structures. You must freeze the set before you can use `call` and `url`. So remember to call freeze after you are done adding routes.

    # File lib/rack/mount/route_set.rb, line 261
    def freeze
      unless frozen?
        rehash

        @recognition_key_analyzer = nil
        @generation_key_analyzer  = nil
        @valid_conditions         = nil

        @routes.each { |route| route.freeze }
        @routes.freeze
      end

      super
    end

length() click to toggle source

Number of routes in the set

    # File lib/rack/mount/route_set.rb, line 243
    def length
      @routes.length
    end

recognize(obj) click to toggle source

    # File lib/rack/mount/route_set.rb, line 78
    def recognize(obj)
      raise 'route set not finalized' unless @recognition_graph

      cache = {}
      keys = @recognition_keys.map { |key|
        if key.respond_to?(:call)
          key.call(cache, obj)
        else
          obj.send(key)
        end
      }

      @recognition_graph[*keys].each do |route|
        matches = {}
        params  = route.defaults.dup

        if route.conditions.all? { |method, condition|
            value = obj.send(method)
            if condition.is_a?(Regexp) && (m = value.match(condition))
              matches[method] = m
              captures = m.captures
              route.named_captures[method].each do |k, i|
                if v = captures[i]
                  params[k] = v
                end
              end
              true
            elsif value == condition
              true
            else
              false
            end
          }
          if block_given?
            yield route, matches, params
          else
            return route, matches, params
          end
        end
      end

      nil
    end

url(env, *args) click to toggle source

Generates a url from Rack env and identifiers or significant keys.

To generate a url by named route, pass the name in as a `Symbol`.

    url(env, :dashboard) # => "/dashboard"

Additional parameters can be passed in as a hash

    url(env, :people, :id => "1") # => "/people/1"

If no name route is given, it will fall back to a slower generation search.

    url(env, :controller => "people", :action => "show", :id => "1")
      # => "/people/1"

    # File lib/rack/mount/route_set.rb, line 167
    def url(env, *args)
      named_route, params = nil, {}

      case args.length
      when 2
        named_route, params = args[0], args[1].dup
      when 1
        if args[0].is_a?(Hash)
          params = args[0].dup
        else
          named_route = args[0]
        end
      else
        raise ArgumentError
      end

      only_path = params.delete(:only_path)
      recall = env[@parameters_key] || {}

      unless result = generate(:all, named_route, params, recall,
          :parameterize => lambda { |name, param| Utils.escape_uri(param) })
        return
      end

      parts, params = result
      return unless parts

      params.each do |k, v|
        if v
          params[k] = v
        else
          params.delete(k)
        end
      end

      req = stubbed_request_class.new(env)
      req._stubbed_values = parts.merge(:query_string => Utils.build_nested_query(params))
      only_path ? req.fullpath : req.url
    end

### Protected Instance Methods

recognition_stats() click to toggle source

    # File lib/rack/mount/route_set.rb, line 297
    def recognition_stats
      { :keys => @recognition_keys,
        :keys_size => @recognition_keys.size,
        :graph_size => @recognition_graph.size,
        :graph_height => @recognition_graph.height,
        :graph_average_height => @recognition_graph.average_height }
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.