aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller/routing.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_controller/routing.rb')
-rw-r--r--actionpack/lib/action_controller/routing.rb63
1 files changed, 56 insertions, 7 deletions
diff --git a/actionpack/lib/action_controller/routing.rb b/actionpack/lib/action_controller/routing.rb
index b25f99c37f..4fa1acf95e 100644
--- a/actionpack/lib/action_controller/routing.rb
+++ b/actionpack/lib/action_controller/routing.rb
@@ -60,6 +60,7 @@ module ActionController
def self.new(string, *args)
return super(string, *args) unless self == Component
case string
+ when /.*;.*/ then SubpathComponent.new(string.split(/;/), *args)
when ':controller' then ControllerComponent.new(:controller, *args)
when /^:(\w+)$/ then DynamicComponent.new($1, *args)
when /^\*(\w+)$/ then PathComponent.new($1, *args)
@@ -68,6 +69,53 @@ module ActionController
end
end
+ class SubpathComponent < Component #:nodoc:
+ attr_reader :parts
+
+ def initialize(parts, *args)
+ @parts = parts.map { |part| Component.new(part, *args) }
+ end
+
+ def write_recognition(g)
+ raise RoutingError, "Subpath components must occur last" unless g.after.empty?
+ g.next_segment
+ g.line "subindex, subpath = 0, #{g.next_segment}.split(/;/)"
+ tweak_recognizer(g).go
+ g.move_forward { |gg| gg.continue }
+ end
+
+ def write_generation(g)
+ raise RoutingError, "Subpath components must occur last" unless g.after.empty?
+ tweak_generator(g).go
+ end
+
+ def key
+ parts.map { |p| p.key }
+ end
+
+ private
+
+ def tweak_recognizer(g)
+ gg = g.dup
+
+ gg.path_name = :subpath
+ gg.base_segment_name = :subsegment
+ gg.base_index_name = :subindex
+ gg.depth = 0
+
+ gg.before, gg.current, gg.after = [], parts.first, (parts[1..-1] || [])
+
+ gg
+ end
+
+ def tweak_generator(g)
+ gg = g.dup
+ gg.before, gg.current, gg.after = [], parts.first, (parts[1..-1] || [])
+ gg.start_subpath!
+ gg
+ end
+ end
+
class StaticComponent < Component #:nodoc:
attr_reader :value
@@ -337,7 +385,7 @@ module ActionController
g = generator.dup
g.share_locals_with generator
g.before, g.current, g.after = [], components.first, (components[1..-1] || [])
-
+
known.each do |key, value|
if key == :controller then ControllerComponent.assign_controller(g, value)
else g.constant_result(key, value)
@@ -354,7 +402,7 @@ module ActionController
end
def initialize_keys
- @keys = (components.collect {|c| c.key} + known.keys).compact
+ @keys = (components.collect {|c| c.key} + known.keys).flatten.compact
@keys.freeze
end
@@ -379,12 +427,12 @@ module ActionController
end
def initialize_hashes(options)
- path_keys = components.collect {|c| c.key }.compact
+ path_keys = components.collect {|c| c.key }.flatten.compact
self.known = {}
defaults = options.delete(:defaults) || {}
conditions = options.delete(:require) || {}
conditions.update(options.delete(:requirements) || {})
-
+
options.each do |k, v|
if path_keys.include?(k) then (v.is_a?(Regexp) ? conditions : defaults)[k] = v
else known[k] = v
@@ -394,7 +442,8 @@ module ActionController
end
def configure_components(defaults, conditions)
- components.each do |component|
+ all_components = components.map { |c| SubpathComponent === c ? c.parts : c }.flatten
+ all_components.each do |component|
if defaults.key?(component.key) then component.default = defaults[component.key]
elsif component.key == :action then component.default = 'index'
elsif component.key == :id then component.default = nil
@@ -405,7 +454,7 @@ module ActionController
end
def add_default_requirements
- component_keys = components.collect {|c| c.key}
+ component_keys = components.collect {|c| c.key}.flatten
known[:action] ||= 'index' unless component_keys.include? :action
end
end
@@ -505,7 +554,7 @@ module ActionController
route.write_recognition(g)
end
end
-
+
eval g.to_s, nil, 'generated/routing/recognition.rb'
return g.to_s
end