Class: ActionController::Routing::RouteSet
- Defined in:
- lib/action_controller/routing.rb
Overview
:nodoc:
Defined Under Namespace
Classes: Mapper, NamedRouteCollection
Instance Attribute Summary collapse
-
#named_routes ⇒ Object
Returns the value of attribute named_routes.
-
#routes ⇒ Object
Returns the value of attribute routes.
Instance Method Summary collapse
- #add_deprecated_named_route(name, deprecated_name) ⇒ Object
- #add_named_route(name, path, options = {}) ⇒ Object
- #add_route(path, options = {}) ⇒ Object
- #build_expiry(options, recall) ⇒ Object
-
#builder ⇒ Object
Subclasses and plugins may override this method to specify a different RouteBuilder instance, so that other route DSL’s can be created.
- #clear! ⇒ Object
- #draw {|Mapper.new(self)| ... } ⇒ Object
- #empty? ⇒ Boolean
-
#extra_keys(options, recall = {}) ⇒ Object
Generate the path indicated by the arguments, and return an array of the keys that were not used to generate it.
-
#extract_request_environment(request) ⇒ Object
Subclasses and plugins may override this method to extract further attributes from the request, for use by route conditions and such.
- #generate(options, recall = {}, method = :generate) ⇒ Object
- #generate_extras(options, recall = {}) ⇒ Object
-
#initialize ⇒ RouteSet
constructor
A new instance of RouteSet.
- #load! ⇒ Object (also: #reload)
- #load_routes! ⇒ Object
- #options_as_params(options) ⇒ Object
-
#raise_named_route_error(options, named_route, named_route_name) ⇒ Object
try to give a helpful error message when named route generation fails.
- #recognize(request) ⇒ Object
- #recognize_path(path, environment = {}) ⇒ Object
- #routes_by_controller ⇒ Object
- #routes_for(options, merged, expire_on) ⇒ Object
- #routes_for_controller_and_action(controller, action) ⇒ Object
- #routes_for_controller_and_action_and_keys(controller, action, keys) ⇒ Object
Constructor Details
#initialize ⇒ RouteSet
Returns a new instance of RouteSet.
1153 1154 1155 1156 |
# File 'lib/action_controller/routing.rb', line 1153 def initialize self.routes = [] self.named_routes = NamedRouteCollection.new end |
Instance Attribute Details
#named_routes ⇒ Object
Returns the value of attribute named_routes.
1151 1152 1153 |
# File 'lib/action_controller/routing.rb', line 1151 def named_routes @named_routes end |
#routes ⇒ Object
Returns the value of attribute routes.
1151 1152 1153 |
# File 'lib/action_controller/routing.rb', line 1151 def routes @routes end |
Instance Method Details
#add_deprecated_named_route(name, deprecated_name) ⇒ Object
1208 1209 1210 |
# File 'lib/action_controller/routing.rb', line 1208 def add_deprecated_named_route(name, deprecated_name) named_routes.define_deprecated_named_route_methods(name, deprecated_name) end |
#add_named_route(name, path, options = {}) ⇒ Object
1204 1205 1206 |
# File 'lib/action_controller/routing.rb', line 1204 def add_named_route(name, path, = {}) named_routes[name] = add_route(path, ) end |
#add_route(path, options = {}) ⇒ Object
1198 1199 1200 1201 1202 |
# File 'lib/action_controller/routing.rb', line 1198 def add_route(path, = {}) route = builder.build(path, ) routes << route route end |
#build_expiry(options, recall) ⇒ Object
1230 1231 1232 1233 1234 1235 |
# File 'lib/action_controller/routing.rb', line 1230 def build_expiry(, recall) recall.inject({}) do |expiry, (key, recalled_value)| expiry[key] = (.key?(key) && [key] != recalled_value) expiry end end |
#builder ⇒ Object
Subclasses and plugins may override this method to specify a different RouteBuilder instance, so that other route DSL’s can be created.
1160 1161 1162 |
# File 'lib/action_controller/routing.rb', line 1160 def builder @builder ||= RouteBuilder.new end |
#clear! ⇒ Object
1170 1171 1172 1173 1174 1175 |
# File 'lib/action_controller/routing.rb', line 1170 def clear! routes.clear named_routes.clear @combined_regexp = nil @routes_by_controller = nil end |
#draw {|Mapper.new(self)| ... } ⇒ Object
1164 1165 1166 1167 1168 |
# File 'lib/action_controller/routing.rb', line 1164 def draw clear! yield Mapper.new(self) named_routes.install end |
#empty? ⇒ Boolean
1177 1178 1179 |
# File 'lib/action_controller/routing.rb', line 1177 def empty? routes.empty? end |
#extra_keys(options, recall = {}) ⇒ Object
Generate the path indicated by the arguments, and return an array of the keys that were not used to generate it.
1239 1240 1241 |
# File 'lib/action_controller/routing.rb', line 1239 def extra_keys(, recall={}) generate_extras(, recall).last end |
#extract_request_environment(request) ⇒ Object
Subclasses and plugins may override this method to extract further attributes from the request, for use by route conditions and such.
1365 1366 1367 |
# File 'lib/action_controller/routing.rb', line 1365 def extract_request_environment(request) { :method => request.method } end |
#generate(options, recall = {}, method = :generate) ⇒ Object
1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 |
# File 'lib/action_controller/routing.rb', line 1247 def generate(, recall = {}, method=:generate) named_route_name = .delete(:use_route) if named_route_name named_route = named_routes[named_route_name] = named_route.parameter_shell.merge() end = () expire_on = build_expiry(, recall) if [:controller] [:controller] = [:controller].to_s end # if the controller has changed, make sure it changes relative to the # current controller module, if any. In other words, if we're currently # on admin/get, and the new controller is 'set', the new controller # should really be admin/set. if !named_route && expire_on[:controller] && [:controller] && [:controller][0] != ?/ old_parts = recall[:controller].split('/') new_parts = [:controller].split('/') parts = old_parts[0..-(new_parts.length + 1)] + new_parts [:controller] = parts.join('/') end # drop the leading '/' on the controller name [:controller] = [:controller][1..-1] if [:controller] && [:controller][0] == ?/ merged = recall.merge() if named_route path = named_route.generate(, merged, expire_on) if path.nil? raise_named_route_error(, named_route, named_route_name) else return path end else merged[:action] ||= 'index' [:action] ||= 'index' controller = merged[:controller] action = merged[:action] raise RoutingError, "Need controller and action!" unless controller && action # don't use the recalled keys when determining which routes to check routes = routes_by_controller[controller][action][.keys.sort_by { |x| x.object_id }] routes.each do |route| results = route.send(method, , merged, expire_on) return results if results && (!results.is_a?(Array) || results.first) end end raise RoutingError, "No route matches #{.inspect}" end |
#generate_extras(options, recall = {}) ⇒ Object
1243 1244 1245 |
# File 'lib/action_controller/routing.rb', line 1243 def generate_extras(, recall={}) generate(, recall, :generate_extras) end |
#load! ⇒ Object Also known as: reload
1181 1182 1183 1184 1185 1186 |
# File 'lib/action_controller/routing.rb', line 1181 def load! Routing.use_controllers! nil # Clear the controller cache so we may discover new ones clear! load_routes! named_routes.install end |
#load_routes! ⇒ Object
1190 1191 1192 1193 1194 1195 1196 |
# File 'lib/action_controller/routing.rb', line 1190 def load_routes! if defined?(RAILS_ROOT) && defined?(::ActionController::Routing::Routes) && self == ::ActionController::Routing::Routes load File.join("#{RAILS_ROOT}/config/routes.rb") else add_route ":controller/:action/:id" end end |
#options_as_params(options) ⇒ Object
1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 |
# File 'lib/action_controller/routing.rb', line 1212 def () # If an explicit :controller was given, always make :action explicit # too, so that action expiry works as expected for things like # # generate({:controller => 'content'}, {:controller => 'content', :action => 'show'}) # # (the above is from the unit tests). In the above case, because the # controller was explicitly given, but no action, the action is implied to # be "index", not the recalled action of "show". # # great fun, eh? = .clone [:action] ||= 'index' if [:controller] [:action] = [:action].to_s if [:action] end |
#raise_named_route_error(options, named_route, named_route_name) ⇒ Object
try to give a helpful error message when named route generation fails
1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 |
# File 'lib/action_controller/routing.rb', line 1303 def raise_named_route_error(, named_route, named_route_name) diff = named_route.requirements.diff() unless diff.empty? raise RoutingError, "#{named_route_name}_url failed to generate from #{.inspect}, expected: #{named_route.requirements.inspect}, diff: #{named_route.requirements.diff().inspect}" else required_segments = named_route.segments.select {|seg| (!seg.optional?) && (!seg.is_a?(DividerSegment)) } required_keys_or_values = required_segments.map { |seg| seg.key rescue seg.value } # we want either the key or the value from the segment raise RoutingError, "#{named_route_name}_url failed to generate from #{.inspect} - you may have ambiguous routes, or you may need to supply additional parameters for this route. content_url has the following required parameters: #{required_keys_or_values.inspect} - are they all satisifed?" end end |
#recognize(request) ⇒ Object
1314 1315 1316 1317 1318 |
# File 'lib/action_controller/routing.rb', line 1314 def recognize(request) params = recognize_path(request.path, extract_request_environment(request)) request.path_parameters = params.with_indifferent_access "#{params[:controller].camelize}Controller".constantize end |
#recognize_path(path, environment = {}) ⇒ Object
1320 1321 1322 1323 1324 1325 1326 |
# File 'lib/action_controller/routing.rb', line 1320 def recognize_path(path, environment={}) path = CGI.unescape(path) routes.each do |route| result = route.recognize(path, environment) and return result end raise RoutingError, "no route found to match #{path.inspect} with #{environment.inspect}" end |
#routes_by_controller ⇒ Object
1328 1329 1330 1331 1332 1333 1334 1335 1336 |
# File 'lib/action_controller/routing.rb', line 1328 def routes_by_controller @routes_by_controller ||= Hash.new do |controller_hash, controller| controller_hash[controller] = Hash.new do |action_hash, action| action_hash[action] = Hash.new do |key_hash, keys| key_hash[keys] = routes_for_controller_and_action_and_keys(controller, action, keys) end end end end |
#routes_for(options, merged, expire_on) ⇒ Object
1338 1339 1340 1341 1342 1343 1344 1345 |
# File 'lib/action_controller/routing.rb', line 1338 def routes_for(, merged, expire_on) raise "Need controller and action!" unless controller && action controller = merged[:controller] merged = if expire_on[:controller] action = merged[:action] || 'index' routes_by_controller[controller][action][merged.keys] end |
#routes_for_controller_and_action(controller, action) ⇒ Object
1347 1348 1349 1350 1351 1352 |
# File 'lib/action_controller/routing.rb', line 1347 def routes_for_controller_and_action(controller, action) selected = routes.select do |route| route.matches_controller_and_action? controller, action end (selected.length == routes.length) ? routes : selected end |
#routes_for_controller_and_action_and_keys(controller, action, keys) ⇒ Object
1354 1355 1356 1357 1358 1359 1360 1361 |
# File 'lib/action_controller/routing.rb', line 1354 def routes_for_controller_and_action_and_keys(controller, action, keys) selected = routes.select do |route| route.matches_controller_and_action? controller, action end selected.sort_by do |route| (keys - route.significant_keys).length end end |