Class: Merb::Router

Inherits:
Object show all
Defined in:
merb-core/lib/merb-core/dispatch/router.rb,
merb-core/lib/merb-core/dispatch/router/route.rb,
merb-core/lib/merb-core/dispatch/router/behavior.rb,
merb-core/lib/merb-core/dispatch/router/resources.rb,
merb-core/lib/merb-core/dispatch/router/cached_proc.rb

Overview

Router stores route definitions and finds the first route that matches the incoming request URL.

Then information from route is used by dispatcher to call action on the controller.

Routes compilation.

The most interesting method of Router (and heart of route matching machinery) is match method generated on the fly from routes definitions. It is called routes compilation. Generated match method body contains one if/elsif statement that picks the first matching route definition and sets values to named parameters of the route.

Compilation is synchronized by mutex.

Defined Under Namespace

Modules: Resources Classes: Behavior, CachedProc, GenerationError, NotCompiledError, ResourceBehavior, Route, RouteNotFound

Class Attribute Summary (collapse)

Class Method Summary (collapse)

Class Attribute Details

+ (Object) around_match

A block that will be run around route matching. This block must yield in order for the actual matching to happen.



82
83
84
# File 'merb-core/lib/merb-core/dispatch/router.rb', line 82

def around_match
  @around_match
end

+ (Object) named_routes

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

A hash containing all the named application routes. The names are absolute (as in, all routes named in a namespace will contain the name of the namespace).



49
50
51
# File 'merb-core/lib/merb-core/dispatch/router.rb', line 49

def named_routes
  @named_routes
end

+ (Object) resource_routes

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

A hash of all the application resource routes. The key of the hash is an array with each element containing the "path" for the resource for example, given the following resource routes:

resources :users do
  resources :comments
end

The show comment route will have a key of ["User", "Comment"]



62
63
64
# File 'merb-core/lib/merb-core/dispatch/router.rb', line 62

def resource_routes
  @resource_routes
end

+ (Object) root_behavior

The starting point for route definition. Any route defined in a prepare block will defined in context of this behavior.

Merb::Router.root_behavior = Merb::Router.root_bavior.match("/hello")

In the previous example, all routes will have the path prefix /hello. It is important to note that this attribute must be set before any routes are defined in order for the behavior to be applied to the routes.



76
77
78
# File 'merb-core/lib/merb-core/dispatch/router.rb', line 76

def root_behavior
  @root_behavior
end

+ (Object) routes

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

An array containing all the application routes in order of priority.



42
43
44
# File 'merb-core/lib/merb-core/dispatch/router.rb', line 42

def routes
  @routes
end

Class Method Details

+ (nil) extensions { ... }

Add functionality to the router. This can be in the form of including a new module or directly defining new methods.

Merb::Router.extensions do
  def domain(name, domain, options={}, &block)
    match(:domain => domain).namespace(name, :path => nil, &block)
  end
end

In this case, a method 'domain' will be available to the route builder which will create namespaces around domains instead of path prefixes.

This can then be used as follows.

Merb::Router.prepare do
  domain(:admin, "my-admin.com") do
    # ... routes come here ...
  end
end

Yields:

  • A block of code used to extend the route builder with. This can be including a module or directly defining some new methods that should be available to building routes.

Returns:

  • (nil)


308
309
310
# File 'merb-core/lib/merb-core/dispatch/router.rb', line 308

def extensions(&block)
  Router::Behavior.class_eval(&block)
end

+ (Object) match_before_compilation(request) Also known as: match

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

This method is aliased as match but this method gets overridden with the actual match method (generated from the routes definitions) after being compiled. This method is only ever called before routes are compiled.

A placeholder for the compiled match method.

Raises:



152
153
154
# File 'merb-core/lib/merb-core/dispatch/router.rb', line 152

def match_before_compilation(request) #:nodoc:
  raise NotCompiledError, "The routes have not been compiled yet"
end

+ (Merb::Router) prepare(first = [], last = [], &block)

Creates a route building context and evaluates the block in it. A copy of root_behavior (and instance of Behavior) is copied as the context.

Parameters:

  • first (Array) (defaults to: [])

    An array containing routes that should be prepended to the routes defined in the block.

  • last (Array) (defaults to: [])

    An array containing routes that should be appended to the routes defined in the block.

Returns:

  • (Merb::Router)

    Returns self to allow chaining of methods.



98
99
100
101
102
103
104
# File 'merb-core/lib/merb-core/dispatch/router.rb', line 98

def prepare(first = [], last = [], &block)
  @routes = []
  root_behavior._with_proxy(&block)
  @routes = first + @routes + last
  compile
  self
end

+ (Object) reset!

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Clears the routing table. Route generation and request matching won't work anymore until a new routing table is built.



110
111
112
113
114
115
# File 'merb-core/lib/merb-core/dispatch/router.rb', line 110

def reset!
  class << self
    alias_method :match, :match_before_compilation
  end
  self.routes, self.named_routes, self.resource_routes = [], {}, {}
end

+ (String) resource(*args)

Generates a URL from the resource(s)

Merb::Router.prepare do
  resources :users do
    resources :comments
  end
end

resource(:users)            # => /users
resource(@user)             # => /users/10
resource(@user, :comments)  # => /users/10/comments
resource(@user, @comment)   # => /users/10/comments/15
resource(:users, :new)      # => /users/new
resource(:@user, :edit)     # => /users/10/edit

Parameters:

  • resources (Symbol, Object)

    The resources for which the URL should be generated. These resources should be specified in the router.rb file using #resources and #resource.

  • options (Hash)

    Any extra parameters that are needed to generate the URL.

Returns:

  • (String)

    The generated URL.



256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'merb-core/lib/merb-core/dispatch/router.rb', line 256

def resource(*args)
  defaults = args.pop
  options  = extract_options_from_args!(args) || {}
  key      = []
  params   = []
  
  args.each do |arg|
    if arg.is_a?(Symbol) || arg.is_a?(String)
      key << arg.to_s
    else
      key << arg.class.to_s
      params << arg
    end
  end
  
  unless route = Merb::Router.resource_routes[key]
    raise Merb::Router::GenerationError, "Resource route not found: #{args.inspect}"
  end

  params << options
  
  route.generate(params, defaults, true)
end

+ (Array<Integer, Hash>) route_for(request)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Finds route matching URI of the request and returns a tuple of [route index, route params]. This method is called by the dispatcher and isn't as useful in applications.

Parameters:

Returns:

  • (Array<Integer, Hash>)

    Two-tuple: route index and route parameters. Route parameters are :controller, :action and all the named segments of the route.



128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'merb-core/lib/merb-core/dispatch/router.rb', line 128

def route_for(request)
  index, params = if @around_match
    send(@around_match, request) { match(request) }
  else
    match(request)
  end
  route = routes[index] if index
  if !route
    raise ControllerExceptions::NotFound, 
      "No routes match the request: #{request.uri}"
  end
  [route, params]
end

+ (String) url(name, params) + (String) url(*args) + (String) url(name, anon_params)

Generate URLs.

There are three possible ways to use this method:

  1. If you have a named route, you can specify the route as the first parameter as a symbol and any paramters in a hash.
  2. You can generate the default route by just passing the params hash.
  3. You can use the anonymous parameters. This allows you to specify the parameters to a named route in the order they appear in the router.

Examples:

Named Route


Merb::Router.prepare do
  match("/articles/:title").to(:controller => :articles, :action => :show).name("articles")
end

url(:articles, :title => "new_article")

Default Route


Merb::Router.prepare do
  default_routes
end

url(:controller => "articles", :action => "new")

Anonymous Paramters


Merb::Router.prepare do
  match("/articles/:year/:month/:title").to(:controller => :articles, :action => :show).name("articles")
end

url(:articles, 2008, 10, "test_article")

Overloads:

  • + (String) url(name, params)

    Named Route

    Parameters:

    • name (Symbol)

      The name of the route.

    • params (Hash)

      Parameters for route generation.

  • + (String) url(*args)

    Default Route

    Parameters:

    • args (Hash)

      Parameters for route generation. This route will use the default route.

  • + (String) url(name, anon_params)

    Anonymous Parameters

    Parameters:

    • name (Symbol)

      The name of the route.

    • anon_params (Array)

      An array of anonymous parameters to generate the route with. These parameters are assigned to the route parameters in the order that they are passed.

Returns:

  • (String)

    The generated URL.



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'merb-core/lib/merb-core/dispatch/router.rb', line 213

def url(name, *args)
  if name.is_a?(Route)
    route = name
  else
    unless name.is_a?(Symbol)
      args.unshift(name)
      name = :default
    end

    unless route = Merb::Router.named_routes[name]
      raise Merb::Router::GenerationError, "Named route not found: #{name}"
    end
  end
  
  defaults = args.pop
  
  route.generate(args, defaults)
end