| Class | ActionController::Routing::RouteSet |
| In: |
vendor/rails/actionpack/lib/action_controller/routing.rb
|
| Parent: | Object |
| named_routes | [RW] | |
| routes | [RW] |
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1084
1084: def initialize
1085: self.routes = []
1086: self.named_routes = NamedRouteCollection.new
1087: end
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1134
1134: def add_named_route(name, path, options = {})
1135: named_routes[name] = add_route(path, options)
1136: end
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1128
1128: def add_route(path, options = {})
1129: route = builder.build(path, options)
1130: routes << route
1131: route
1132: end
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1157
1157: def build_expiry(options, recall)
1158: recall.inject({}) do |expiry, (key, recalled_value)|
1159: expiry[key] = (options.key?(key) && options[key] != recalled_value)
1160: expiry
1161: end
1162: end
Subclasses and plugins may override this method to specify a different RouteBuilder instance, so that other route DSL’s can be created.
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1091
1091: def builder
1092: @builder ||= RouteBuilder.new
1093: end
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1101
1101: def clear!
1102: routes.clear
1103: named_routes.clear
1104: @combined_regexp = nil
1105: @routes_by_controller = nil
1106: end
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1095
1095: def draw
1096: clear!
1097: yield Mapper.new(self)
1098: named_routes.install
1099: end
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1108
1108: def empty?
1109: routes.empty?
1110: end
Generate the path indicated by the arguments, and return an array of the keys that were not used to generate it.
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1166
1166: def extra_keys(options, recall={})
1167: generate_extras(options, recall).last
1168: end
Subclasses and plugins may override this method to extract further attributes from the request, for use by route conditions and such.
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1275
1275: def extract_request_environment(request)
1276: { :method => request.method }
1277: end
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1174
1174: def generate(options, recall = {}, method=:generate)
1175: named_route_name = options.delete(:use_route)
1176: if named_route_name
1177: options = options.dup
1178: named_route = named_routes[named_route_name]
1179: options = named_route.parameter_shell.merge(options)
1180: end
1181:
1182: options = options_as_params(options)
1183: expire_on = build_expiry(options, recall)
1184:
1185: # if the controller has changed, make sure it changes relative to the
1186: # current controller module, if any. In other words, if we're currently
1187: # on admin/get, and the new controller is 'set', the new controller
1188: # should really be admin/set.
1189: if !named_route && expire_on[:controller] && options[:controller] && options[:controller][0] != ?/
1190: old_parts = recall[:controller].split('/')
1191: new_parts = options[:controller].split('/')
1192: parts = old_parts[0..-(new_parts.length + 1)] + new_parts
1193: options[:controller] = parts.join('/')
1194: end
1195:
1196: # drop the leading '/' on the controller name
1197: options[:controller] = options[:controller][1..-1] if options[:controller] && options[:controller][0] == ?/
1198: merged = recall.merge(options)
1199:
1200: if named_route
1201: path = named_route.generate(options, merged, expire_on)
1202: raise RoutingError, "#{named_route_name}_url failed to generate from #{options.inspect}, expected: #{named_route.requirements.inspect}, diff: #{named_route.requirements.diff(options).inspect}" if path.nil?
1203: return path
1204: else
1205: merged[:action] ||= 'index'
1206: options[:action] ||= 'index'
1207:
1208: controller = merged[:controller]
1209: action = merged[:action]
1210:
1211: raise RoutingError, "Need controller and action!" unless controller && action
1212: # don't use the recalled keys when determining which routes to check
1213: routes = routes_by_controller[controller][action][options.keys.sort_by { |x| x.object_id }]
1214:
1215: routes.each do |route|
1216: results = route.send(method, options, merged, expire_on)
1217: return results if results
1218: end
1219: end
1220:
1221: raise RoutingError, "No route matches #{options.inspect}"
1222: end
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1170
1170: def generate_extras(options, recall={})
1171: generate(options, recall, :generate_extras)
1172: end
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1112
1112: def load!
1113: clear!
1114: load_routes!
1115: named_routes.install
1116: end
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1120
1120: def load_routes!
1121: if defined?(RAILS_ROOT) && defined?(::ActionController::Routing::Routes) && self == ::ActionController::Routing::Routes
1122: load File.join("#{RAILS_ROOT}/config/routes.rb")
1123: else
1124: add_route ":controller/:action/:id"
1125: end
1126: end
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1138
1138: def options_as_params(options)
1139: # If an explicit :controller was given, always make :action explicit
1140: # too, so that action expiry works as expected for things like
1141: #
1142: # generate({:controller => 'content'}, {:controller => 'content', :action => 'show'})
1143: #
1144: # (the above is from the unit tests). In the above case, because the
1145: # controller was explicitly given, but no action, the action is implied to
1146: # be "index", not the recalled action of "show".
1147: #
1148: # great fun, eh?
1149:
1150: options_as_params = options[:controller] ? { :action => "index" } : {}
1151: options.each do |k, value|
1152: options_as_params[k] = value.to_param
1153: end
1154: options_as_params
1155: end
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1224
1224: def recognize(request)
1225: params = recognize_path(request.path, extract_request_environment(request))
1226: request.path_parameters = params.with_indifferent_access
1227: "#{params[:controller].camelize}Controller".constantize
1228: end
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1230
1230: def recognize_path(path, environment={})
1231: path = CGI.unescape(path)
1232: routes.each do |route|
1233: result = route.recognize(path, environment) and return result
1234: end
1235: raise RoutingError, "no route found to match #{path.inspect} with #{environment.inspect}"
1236: end
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1238
1238: def routes_by_controller
1239: @routes_by_controller ||= Hash.new do |controller_hash, controller|
1240: controller_hash[controller] = Hash.new do |action_hash, action|
1241: action_hash[action] = Hash.new do |key_hash, keys|
1242: key_hash[keys] = routes_for_controller_and_action_and_keys(controller, action, keys)
1243: end
1244: end
1245: end
1246: end
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1248
1248: def routes_for(options, merged, expire_on)
1249: raise "Need controller and action!" unless controller && action
1250: controller = merged[:controller]
1251: merged = options if expire_on[:controller]
1252: action = merged[:action] || 'index'
1253:
1254: routes_by_controller[controller][action][merged.keys]
1255: end
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1257
1257: def routes_for_controller_and_action(controller, action)
1258: selected = routes.select do |route|
1259: route.matches_controller_and_action? controller, action
1260: end
1261: (selected.length == routes.length) ? routes : selected
1262: end
# File vendor/rails/actionpack/lib/action_controller/routing.rb, line 1264
1264: def routes_for_controller_and_action_and_keys(controller, action, keys)
1265: selected = routes.select do |route|
1266: route.matches_controller_and_action? controller, action
1267: end
1268: selected.sort_by do |route|
1269: (keys - route.significant_keys).length
1270: end
1271: end