Class: ActionController::Routing::Route
- Defined in:
- lib/action_controller/routing.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.
358 359 360 361 362 363 |
# File 'lib/action_controller/routing.rb', line 358 def initialize @segments = [] @requirements = {} @conditions = {} @optimise = true end |
Instance Attribute Details
#conditions ⇒ Object
Returns the value of attribute conditions.
356 357 358 |
# File 'lib/action_controller/routing.rb', line 356 def conditions @conditions end |
#optimise ⇒ Object
Returns the value of attribute optimise.
356 357 358 |
# File 'lib/action_controller/routing.rb', line 356 def optimise @optimise end |
#requirements ⇒ Object
Returns the value of attribute requirements.
356 357 358 |
# File 'lib/action_controller/routing.rb', line 356 def requirements @requirements end |
#segments ⇒ Object
Returns the value of attribute segments.
356 357 358 |
# File 'lib/action_controller/routing.rb', line 356 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.
484 485 486 487 488 |
# File 'lib/action_controller/routing.rb', line 484 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.
504 505 506 507 508 509 510 511 512 513 514 |
# File 'lib/action_controller/routing.rb', line 504 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.
550 551 552 553 554 555 556 557 558 559 560 561 |
# File 'lib/action_controller/routing.rb', line 550 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.)
496 497 498 |
# File 'lib/action_controller/routing.rb', line 496 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.
472 473 474 475 |
# File 'lib/action_controller/routing.rb', line 472 def generate(, hash, expire_on = {}) write_generation generate , hash, expire_on end |
#generate_extras(options, hash, expire_on = {}) ⇒ Object
477 478 479 480 |
# File 'lib/action_controller/routing.rb', line 477 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.
406 407 408 409 410 |
# File 'lib/action_controller/routing.rb', line 406 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.
414 415 416 417 418 419 420 421 422 423 424 |
# File 'lib/action_controller/routing.rb', line 414 def generation_requirements requirement_conditions = requirements.collect do |key, req| if req.is_a? Regexp value_regexp = Regexp.new "\\A#{req.source}\\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
426 427 428 |
# File 'lib/action_controller/routing.rb', line 426 def generation_structure segments.last.string_structure segments[0..-2] end |
#matches_controller_and_action?(controller, action) ⇒ Boolean
563 564 565 566 567 568 569 570 571 572 |
# File 'lib/action_controller/routing.rb', line 563 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.
367 368 369 |
# File 'lib/action_controller/routing.rb', line 367 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+/
529 530 531 532 533 534 535 |
# File 'lib/action_controller/routing.rb', line 529 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.
445 446 447 448 449 |
# File 'lib/action_controller/routing.rb', line 445 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.
461 462 463 464 465 466 467 468 469 |
# File 'lib/action_controller/routing.rb', line 461 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.
452 453 454 455 456 457 458 |
# File 'lib/action_controller/routing.rb', line 452 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.
517 518 519 520 |
# File 'lib/action_controller/routing.rb', line 517 def recognize(path, environment={}) write_recognition recognize path, environment end |
#segment_keys ⇒ Object
371 372 373 374 375 |
# File 'lib/action_controller/routing.rb', line 371 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.
540 541 542 543 544 545 546 |
# File 'lib/action_controller/routing.rb', line 540 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
574 575 576 577 578 579 |
# File 'lib/action_controller/routing.rb', line 574 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.
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 |
# File 'lib/action_controller/routing.rb', line 378 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.
431 432 433 434 435 436 437 438 439 440 |
# File 'lib/action_controller/routing.rb', line 431 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 |