Class: ActionController::Routing::Route
- Defined in:
- lib/action_controller/routing/route.rb
Overview
:nodoc:
Instance Attribute Summary collapse
-
#conditions ⇒ Object
Returns the value of attribute conditions.
-
#optimise ⇒ Object
Returns the value of attribute optimise.
-
#requirements ⇒ Object
Returns the value of attribute requirements.
-
#segments ⇒ Object
Returns the value of attribute segments.
Instance Method Summary collapse
-
#append_query_string(path, hash, query_keys = nil) ⇒ Object
Generate the query string with any extra keys in the hash and append it to the given path, returning the new path.
-
#build_query_string(hash, only_keys = nil) ⇒ Object
Build a query string from the keys of the given hash.
-
#defaults ⇒ Object
Return a hash of key/value pairs representing the keys in the route that have defaults, or which are specified by non-regexp requirements.
-
#extra_keys(hash, recall = {}) ⇒ Object
Determine which keys in the given hash are “extra”.
-
#generate(options, hash, expire_on = {}) ⇒ Object
Write the real generation implementation and then resend the message.
- #generate_extras(options, hash, expire_on = {}) ⇒ Object
-
#generation_extraction ⇒ Object
Build several lines of code that extract values from the options hash.
-
#generation_requirements ⇒ Object
Produce a condition expression that will check the requirements of this route upon generation.
- #generation_structure ⇒ Object
-
#initialize ⇒ Route
constructor
A new instance of Route.
- #matches_controller_and_action?(controller, action) ⇒ Boolean
-
#optimise? ⇒ Boolean
Indicates whether the routes should be optimised with the string interpolation version of the named routes methods.
-
#parameter_shell ⇒ Object
A route’s parameter shell contains parameter values that are not in the route’s path, but should be placed in the recognized hash.
-
#recognition_conditions ⇒ Object
Plugins may override this method to add other conditions, like checks on host, subdomain, and so forth.
-
#recognition_extraction ⇒ Object
Write the code to extract the parameters from a matched route.
-
#recognition_pattern(wrap = true) ⇒ Object
Build the regular expression pattern that will match this route.
-
#recognize(path, environment = {}) ⇒ Object
Write the real recognition implementation and then resend the message.
- #segment_keys ⇒ Object
-
#significant_keys ⇒ Object
Return an array containing all the keys that are used in this route.
- #to_s ⇒ Object
-
#write_generation ⇒ Object
Write and compile a
generate
method for this Route. -
#write_recognition ⇒ Object
Write and compile a
recognize
method for this Route.
Constructor Details
#initialize ⇒ Route
Returns a new instance of Route.
6 7 8 9 10 11 |
# File 'lib/action_controller/routing/route.rb', line 6 def initialize @segments = [] @requirements = {} @conditions = {} @optimise = true end |
Instance Attribute Details
#conditions ⇒ Object
Returns the value of attribute conditions.
4 5 6 |
# File 'lib/action_controller/routing/route.rb', line 4 def conditions @conditions end |
#optimise ⇒ Object
Returns the value of attribute optimise.
4 5 6 |
# File 'lib/action_controller/routing/route.rb', line 4 def optimise @optimise end |
#requirements ⇒ Object
Returns the value of attribute requirements.
4 5 6 |
# File 'lib/action_controller/routing/route.rb', line 4 def requirements @requirements end |
#segments ⇒ Object
Returns the value of attribute segments.
4 5 6 |
# File 'lib/action_controller/routing/route.rb', line 4 def segments @segments end |
Instance Method Details
#append_query_string(path, hash, query_keys = nil) ⇒ Object
Generate the query string with any extra keys in the hash and append it to the given path, returning the new path.
132 133 134 135 136 |
# File 'lib/action_controller/routing/route.rb', line 132 def append_query_string(path, hash, query_keys=nil) return nil unless path query_keys ||= extra_keys(hash) "#{path}#{build_query_string(hash, query_keys)}" end |
#build_query_string(hash, only_keys = nil) ⇒ Object
Build a query string from the keys of the given hash. If only_keys
is given (as an array), only the keys indicated will be used to build the query string. The query string will correctly build array parameter values.
152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/action_controller/routing/route.rb', line 152 def build_query_string(hash, only_keys = nil) elements = [] (only_keys || hash.keys).each do |key| if value = hash[key] elements << value.to_query(key) end end elements.empty? ? '' : "?#{elements.sort * '&'}" end |
#defaults ⇒ Object
Return a hash of key/value pairs representing the keys in the route that have defaults, or which are specified by non-regexp requirements.
198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/action_controller/routing/route.rb', line 198 def defaults @defaults ||= returning({}) do |hash| segments.each do |segment| next unless segment.respond_to? :default hash[segment.key] = segment.default unless segment.default.nil? end requirements.each do |key,req| next if Regexp === req || req.nil? hash[key] = req end end end |
#extra_keys(hash, recall = {}) ⇒ Object
Determine which keys in the given hash are “extra”. Extra keys are those that were not used to generate a particular route. The extra keys also do not include those recalled from the prior request, nor do they include any keys that were implied in the route (like a :controller
that is required, but not explicitly used in the text of the route.)
144 145 146 |
# File 'lib/action_controller/routing/route.rb', line 144 def extra_keys(hash, recall={}) (hash || {}).keys.map { |k| k.to_sym } - (recall || {}).keys - significant_keys end |
#generate(options, hash, expire_on = {}) ⇒ Object
Write the real generation implementation and then resend the message.
120 121 122 123 |
# File 'lib/action_controller/routing/route.rb', line 120 def generate(, hash, expire_on = {}) write_generation generate , hash, expire_on end |
#generate_extras(options, hash, expire_on = {}) ⇒ Object
125 126 127 128 |
# File 'lib/action_controller/routing/route.rb', line 125 def generate_extras(, hash, expire_on = {}) write_generation generate_extras , hash, expire_on end |
#generation_extraction ⇒ Object
Build several lines of code that extract values from the options hash. If any of the values are missing or rejected then a return will be executed.
54 55 56 57 58 |
# File 'lib/action_controller/routing/route.rb', line 54 def generation_extraction segments.collect do |segment| segment.extraction_code end.compact * "\n" end |
#generation_requirements ⇒ Object
Produce a condition expression that will check the requirements of this route upon generation.
62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/action_controller/routing/route.rb', line 62 def generation_requirements requirement_conditions = requirements.collect do |key, req| if req.is_a? Regexp value_regexp = Regexp.new "\\A#{req.to_s}\\Z" "hash[:#{key}] && #{value_regexp.inspect} =~ options[:#{key}]" else "hash[:#{key}] == #{req.inspect}" end end requirement_conditions * ' && ' unless requirement_conditions.empty? end |
#generation_structure ⇒ Object
74 75 76 |
# File 'lib/action_controller/routing/route.rb', line 74 def generation_structure segments.last.string_structure segments[0..-2] end |
#matches_controller_and_action?(controller, action) ⇒ Boolean
211 212 213 214 215 216 217 218 219 220 |
# File 'lib/action_controller/routing/route.rb', line 211 def matches_controller_and_action?(controller, action) unless defined? @matching_prepared @controller_requirement = requirement_for(:controller) @action_requirement = requirement_for(:action) @matching_prepared = true end (@controller_requirement.nil? || @controller_requirement === controller) && (@action_requirement.nil? || @action_requirement === action) end |
#optimise? ⇒ Boolean
Indicates whether the routes should be optimised with the string interpolation version of the named routes methods.
15 16 17 |
# File 'lib/action_controller/routing/route.rb', line 15 def optimise? @optimise && ActionController::Base::optimise_named_routes end |
#parameter_shell ⇒ Object
A route’s parameter shell contains parameter values that are not in the route’s path, but should be placed in the recognized hash.
For example, +=> ‘pages’, :action => ‘show’ is the shell for the route:
map.connect '/page/:id', :controller => 'pages', :action => 'show', :id => /\d+/
177 178 179 180 181 182 183 |
# File 'lib/action_controller/routing/route.rb', line 177 def parameter_shell @parameter_shell ||= returning({}) do |shell| requirements.each do |key, requirement| shell[key] = requirement unless requirement.is_a? Regexp end end end |
#recognition_conditions ⇒ Object
Plugins may override this method to add other conditions, like checks on host, subdomain, and so forth. Note that changes here only affect route recognition, not generation.
93 94 95 96 97 |
# File 'lib/action_controller/routing/route.rb', line 93 def recognition_conditions result = ["(match = #{Regexp.new(recognition_pattern).inspect}.match(path))"] result << "conditions[:method] === env[:method]" if conditions[:method] result end |
#recognition_extraction ⇒ Object
Write the code to extract the parameters from a matched route.
109 110 111 112 113 114 115 116 117 |
# File 'lib/action_controller/routing/route.rb', line 109 def recognition_extraction next_capture = 1 extraction = segments.collect do |segment| x = segment.match_extraction(next_capture) next_capture += Regexp.new(segment.regexp_chunk).number_of_captures x end extraction.compact end |
#recognition_pattern(wrap = true) ⇒ Object
Build the regular expression pattern that will match this route.
100 101 102 103 104 105 106 |
# File 'lib/action_controller/routing/route.rb', line 100 def recognition_pattern(wrap = true) pattern = '' segments.reverse_each do |segment| pattern = segment.build_pattern pattern end wrap ? ("\\A" + pattern + "\\Z") : pattern end |
#recognize(path, environment = {}) ⇒ Object
Write the real recognition implementation and then resend the message.
165 166 167 168 |
# File 'lib/action_controller/routing/route.rb', line 165 def recognize(path, environment={}) write_recognition recognize path, environment end |
#segment_keys ⇒ Object
19 20 21 22 23 |
# File 'lib/action_controller/routing/route.rb', line 19 def segment_keys segments.collect do |segment| segment.key if segment.respond_to? :key end.compact end |
#significant_keys ⇒ Object
Return an array containing all the keys that are used in this route. This includes keys that appear inside the path, and keys that have requirements placed upon them.
188 189 190 191 192 193 194 |
# File 'lib/action_controller/routing/route.rb', line 188 def significant_keys @significant_keys ||= returning [] do |sk| segments.each { |segment| sk << segment.key if segment.respond_to? :key } sk.concat requirements.keys sk.uniq! end end |
#to_s ⇒ Object
222 223 224 225 226 227 |
# File 'lib/action_controller/routing/route.rb', line 222 def to_s @to_s ||= begin segs = segments.inject("") { |str,s| str << s.to_s } "%-6s %-40s %s" % [(conditions[:method] || :any).to_s.upcase, segs, requirements.inspect] end end |
#write_generation ⇒ Object
Write and compile a generate
method for this Route.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/action_controller/routing/route.rb', line 26 def write_generation # Build the main body of the generation body = "expired = false\n#{generation_extraction}\n#{generation_structure}" # If we have conditions that must be tested first, nest the body inside an if body = "if #{generation_requirements}\n#{body}\nend" if generation_requirements args = "options, hash, expire_on = {}" # Nest the body inside of a def block, and then compile it. raw_method = method_decl = "def generate_raw(#{args})\npath = begin\n#{body}\nend\n[path, hash]\nend" instance_eval method_decl, "generated code (#{__FILE__}:#{__LINE__})" # expire_on.keys == recall.keys; in other words, the keys in the expire_on hash # are the same as the keys that were recalled from the previous request. Thus, # we can use the expire_on.keys to determine which keys ought to be used to build # the query string. (Never use keys from the recalled request when building the # query string.) method_decl = "def generate(#{args})\npath, hash = generate_raw(options, hash, expire_on)\nappend_query_string(path, hash, extra_keys(options))\nend" instance_eval method_decl, "generated code (#{__FILE__}:#{__LINE__})" method_decl = "def generate_extras(#{args})\npath, hash = generate_raw(options, hash, expire_on)\n[path, extra_keys(options)]\nend" instance_eval method_decl, "generated code (#{__FILE__}:#{__LINE__})" raw_method end |
#write_recognition ⇒ Object
Write and compile a recognize
method for this Route.
79 80 81 82 83 84 85 86 87 88 |
# File 'lib/action_controller/routing/route.rb', line 79 def write_recognition # Create an if structure to extract the params from a match if it occurs. body = "params = parameter_shell.dup\n#{recognition_extraction * "\n"}\nparams" body = "if #{recognition_conditions.join(" && ")}\n#{body}\nend" # Build the method declaration and compile it method_decl = "def recognize(path, env={})\n#{body}\nend" instance_eval method_decl, "generated code (#{__FILE__}:#{__LINE__})" method_decl end |