Class: Merb::Router

Inherits:
Object show all
Defined in:
lib/merb-core/dispatch/router.rb,
lib/merb-core/dispatch/router/route.rb,
lib/merb-core/dispatch/router/behavior.rb,
lib/merb-core/dispatch/router/resources.rb,
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

.named_routesObject



39
40
41
# File 'lib/merb-core/dispatch/router.rb', line 39

def named_routes
  @named_routes
end

.resource_routesObject



39
40
41
# File 'lib/merb-core/dispatch/router.rb', line 39

def resource_routes
  @resource_routes
end

.root_behaviorObject



39
40
41
# File 'lib/merb-core/dispatch/router.rb', line 39

def root_behavior
  @root_behavior
end

.routesObject



39
40
41
# File 'lib/merb-core/dispatch/router.rb', line 39

def routes
  @routes
end

Class Method Details

.append(&block) ⇒ Object

Appends route in the block to routing table.



69
70
71
# File 'lib/merb-core/dispatch/router.rb', line 69

def append(&block)
  prepare(routes, [], &block)
end

.extensions(&block) ⇒ Object

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

Parameters

&block<Block>

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

Example

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



271
272
273
# File 'lib/merb-core/dispatch/router.rb', line 271

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

.match_before_compilation(request) ⇒ Object 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.

A placeholder for the compiled match method.

Notes

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.

Raises

NotCompiledError

routes have not been compiled yet.

Raises:



126
127
128
# File 'lib/merb-core/dispatch/router.rb', line 126

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

.prepare(first = [], last = [], &block) ⇒ Object

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>

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

last<Array>

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.



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

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

.prepend(&block) ⇒ Object

Prepends routes in the block to routing table.



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

def prepend(&block)
  prepare([], routes, &block)
end

.reset!Object

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.



84
85
86
87
88
89
# File 'lib/merb-core/dispatch/router.rb', line 84

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

.resource(*args) ⇒ Object

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.

Generates a URL from the resource(s)

Parameters

resources<Symbol,Object>

The identifiers for the resource route to generate. These can either be symbols or objects. Symbols denote resource collection routes and objects denote the members.

params<Hash>

Any extra parameters needed to generate the route.

Returns

String

The generated URL



216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/merb-core/dispatch/router.rb', line 216

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
  
  params << options
  
  unless route = Merb::Router.resource_routes[key]
    raise Merb::Router::GenerationError, "Resource route not found: #{args.inspect}"
  end
  
  route.generate(params, defaults)
end

.route_for(request) ⇒ Object

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

request<Merb::Request>

request to match.

Returns

Array[Integer, Hash]

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



104
105
106
107
108
109
110
111
112
# File 'lib/merb-core/dispatch/router.rb', line 104

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

.url(name, *args) ⇒ Object

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.

There are three possible ways to use this method. First, if you have a named route, you can specify the route as the first parameter as a symbol and any paramters in a hash. Second, you can generate the default route by just passing the params hash, just passing the params hash. Finally, 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.

Parameters(Named Route)

name<Symbol>

The name of the route.

args<Hash>

Parameters for the route generation.

Parameters(Default Route)

args<Hash>

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

Parameters(Anonymous Parameters)

name<Symbol>

The name of the route.

args<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.

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”)



186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/merb-core/dispatch/router.rb', line 186

def url(name, *args)
  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
  
  defaults = args.pop
  
  route.generate(args, defaults)
end