Class: Merb::Router
- 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/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
Classes: Behavior, CachedProc, Route
Constant Summary collapse
- SEGMENT_REGEXP =
/(:([a-z_][a-z0-9_]*|:))/
- SEGMENT_REGEXP_WITH_BRACKETS =
/(:[a-z_]+)(\[(\d+)\])?/
- JUST_BRACKETS =
/\[(\d+)\]/
- PARENTHETICAL_SEGMENT_STRING =
"([^\/.,;?]+)".freeze
- @@named_routes =
{}
- @@routes =
[]
- @@compiler_mutex =
Mutex.new
Class Method Summary collapse
-
.append(&block) ⇒ Object
Appends the generated routes to the current routes.
-
.capture(&block) ⇒ Object
Capture any new routes that have been added within the block.
-
.compile ⇒ Object
Defines the match function for this class based on the compiled_statement.
-
.compiled_statement ⇒ Object
Returns String:: A routing lambda statement generated from the routes.
-
.generate(name, params = {}, fallback = {}) ⇒ Object
Generates a URL based on passed options.
-
.generate_for_default_route(params, fallback) ⇒ Object
Generates a URL based on the default route scheme of “/:controller/:action/:id.:format”.
-
.prepare(first = [], last = []) {|Behavior.new({}, { :action => 'index' })| ... } ⇒ Object
Prepares new routes and adds them to existing routes.
-
.prepend(&block) ⇒ Object
Prepends the generated routes to the current routes.
-
.reset! ⇒ Object
Clear all routes.
-
.route_for(request) ⇒ Object
Finds route matching URI of the request and returns a tuple of [route index, route params].
Class Method Details
.append(&block) ⇒ Object
Appends the generated routes to the current routes.
Parameters
- &block
-
A block that generates new routes when yielded a new Behavior.
65 66 67 |
# File 'lib/merb-core/dispatch/router.rb', line 65 def append(&block) prepare(@@routes, [], &block) end |
.capture(&block) ⇒ Object
Capture any new routes that have been added within the block.
This utility method lets you track routes that have been added; it doesn’t affect how/which routes are added.
- &block
-
A context in which routes are generated.
100 101 102 103 104 |
# File 'lib/merb-core/dispatch/router.rb', line 100 def capture(&block) routes_before, named_route_keys_before = self.routes.dup, self.named_routes.keys yield [self.routes - routes_before, self.named_routes.except(*named_route_keys_before)] end |
.compile ⇒ Object
Defines the match function for this class based on the compiled_statement.
122 123 124 125 |
# File 'lib/merb-core/dispatch/router.rb', line 122 def compile puts "compiled route: #{compiled_statement}" if $DEBUG eval(compiled_statement, binding, "Generated Code for Router#match(#{__FILE__}:#{__LINE__})", 1) end |
.compiled_statement ⇒ Object
Returns
- String
-
A routing lambda statement generated from the routes.
108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/merb-core/dispatch/router.rb', line 108 def compiled_statement @@compiler_mutex.synchronize do @@compiled_statement = "def match(request)\n" @@compiled_statement << " params = request.params\n" @@compiled_statement << " cached_path = request.path\n cached_method = request.method.to_s\n " @@routes.each_with_index { |route, i| @@compiled_statement << route.compile(i == 0) } @@compiled_statement << " else\n [nil, {}]\n" @@compiled_statement << " end\n" @@compiled_statement << "end" end end |
.generate(name, params = {}, fallback = {}) ⇒ Object
Generates a URL based on passed options.
Parameters
- name<~to_sym, Hash>
-
The name of the route to generate.
- params<Hash, Fixnum, Object>
-
The params to use in the route generation.
- fallback<Hash>
-
Parameters for generating a fallback URL.
Returns
- String
-
The generated URL.
Alternatives
If name is a hash, it will be merged with params and passed on to generate_for_default_route along with fallback.
140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/merb-core/dispatch/router.rb', line 140 def generate(name, params = {}, fallback = {}) params.reject! { |k,v| v.nil? } if params.is_a? Hash if name.is_a? Hash name.reject! { |k,v| v.nil? } return generate_for_default_route(name.merge(params), fallback) end name = name.to_sym unless @@named_routes.key? name raise "Named route not found: #{name}" else @@named_routes[name].generate(params, fallback) end end |
.generate_for_default_route(params, fallback) ⇒ Object
Generates a URL based on the default route scheme of “/:controller/:action/:id.:format”.
Parameters
- params<Hash>
-
The primary parameters to create the route from (see below).
- fallback<Hash>
-
Fallback parameters. Same options as params.
Options (params)
- :controller<~to_s>
-
The controller name. Required.
- :action<~to_s>
-
The action name. Required.
- :id<~to_s>
-
The ID for use in the action.
- :format<~to_s>
-
The format of the preferred response.
Returns
- String
-
The generated URL.
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/merb-core/dispatch/router.rb', line 170 def generate_for_default_route(params, fallback) query_params = params.reject do |k,v| [:controller, :action, :id, :format, :fragment].include?(k.to_sym) end controller = params[:controller] || fallback[:controller] raise "Controller Not Specified" unless controller url = "/#{controller}" if params[:action] || params[:id] || params[:format] || !query_params.empty? action = params[:action] || fallback[:action] raise "Action Not Specified" unless action url += "/#{action}" end if params[:id] url += "/#{params[:id]}" end if format = params[:format] format = fallback[:format] if format == :current url += ".#{format}" end unless query_params.empty? url += "?" + Merb::Request.params_to_query_string(query_params) end if params[:fragment] url += "##{params[:fragment]}" end url end |
.prepare(first = [], last = []) {|Behavior.new({}, { :action => 'index' })| ... } ⇒ Object
Prepares new routes and adds them to existing routes.
Parameters
- first<Array>
-
An array of routes to add before the generated routes.
- last<Array>
-
An array of routes to add after the generated routes.
- &block
-
A block that generates new routes.
Block parameters (&block)
- new_behavior<Behavior>
-
Behavior for child routes.
87 88 89 90 91 92 |
# File 'lib/merb-core/dispatch/router.rb', line 87 def prepare(first = [], last = [], &block) @@routes = [] yield Behavior.new({}, { :action => 'index' }) # defaults @@routes = first + @@routes + last compile end |
.prepend(&block) ⇒ Object
Prepends the generated routes to the current routes.
Parameters
- &block
-
A block that generates new routes when yielded a new Behavior.
74 75 76 |
# File 'lib/merb-core/dispatch/router.rb', line 74 def prepend(&block) prepare([], @@routes, &block) end |
.reset! ⇒ Object
Clear all routes.
56 57 58 |
# File 'lib/merb-core/dispatch/router.rb', line 56 def reset! self.routes, self.named_routes = [], {} end |
.route_for(request) ⇒ Object
Finds route matching URI of the request and returns a tuple of [route index, route params].
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.
45 46 47 48 49 50 51 52 53 |
# File 'lib/merb-core/dispatch/router.rb', line 45 def route_for(request) 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 |