aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_dispatch')
-rw-r--r--actionpack/lib/action_dispatch/http/mime_negotiation.rb2
-rw-r--r--actionpack/lib/action_dispatch/http/url.rb47
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb15
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb81
4 files changed, 83 insertions, 62 deletions
diff --git a/actionpack/lib/action_dispatch/http/mime_negotiation.rb b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
index 5c48a60469..e31f3b823d 100644
--- a/actionpack/lib/action_dispatch/http/mime_negotiation.rb
+++ b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/module/attribute_accessors'
+
module ActionDispatch
module Http
module MimeNegotiation
diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb
index f9dae5dad7..4266ec042e 100644
--- a/actionpack/lib/action_dispatch/http/url.rb
+++ b/actionpack/lib/action_dispatch/http/url.rb
@@ -23,23 +23,6 @@ module ActionDispatch
end
def url_for(options = {})
- if options[:host].blank? && options[:only_path].blank?
- raise ArgumentError, 'Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true'
- end
-
- rewritten_url = ""
-
- unless options[:only_path]
- unless options[:protocol] == false
- rewritten_url << (options[:protocol] || "http")
- rewritten_url << ":" unless rewritten_url.match(%r{:|//})
- end
- rewritten_url << "//" unless rewritten_url.match("//")
- rewritten_url << rewrite_authentication(options)
- rewritten_url << host_or_subdomain_and_domain(options)
- rewritten_url << ":#{options.delete(:port)}" if options[:port]
- end
-
path = ""
path << options.delete(:script_name).to_s.chomp("/")
path << options.delete(:path).to_s
@@ -47,14 +30,36 @@ module ActionDispatch
params = options[:params] || {}
params.reject! {|k,v| v.to_param.nil? }
- rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path)
- rewritten_url << "?#{params.to_query}" unless params.empty?
- rewritten_url << "##{Journey::Router::Utils.escape_fragment(options[:anchor].to_param.to_s)}" if options[:anchor]
- rewritten_url
+ result = build_host_url(options)
+
+ result << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path)
+ result << "?#{params.to_query}" unless params.empty?
+ result << "##{Journey::Router::Utils.escape_fragment(options[:anchor].to_param.to_s)}" if options[:anchor]
+ result
end
private
+ def build_host_url(options)
+ if options[:host].blank? && options[:only_path].blank?
+ raise ArgumentError, 'Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true'
+ end
+
+ result = ""
+
+ unless options[:only_path]
+ unless options[:protocol] == false
+ result << (options[:protocol] || "http")
+ result << ":" unless result.match(%r{:|//})
+ end
+ result << "//" unless result.match("//")
+ result << rewrite_authentication(options)
+ result << host_or_subdomain_and_domain(options)
+ result << ":#{options.delete(:port)}" if options[:port]
+ end
+ result
+ end
+
def named_host?(host)
host && IP_HOST_REGEXP !~ host
end
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index ba4cfb482d..fdc0bfb686 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/hash/except'
+require 'active_support/core_ext/hash/reverse_merge'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/enumerable'
require 'active_support/inflector'
@@ -58,6 +59,16 @@ module ActionDispatch
@options = (@scope[:options] || {}).merge(options)
@path = normalize_path(path)
normalize_options!
+
+ via_all = @options.delete(:via) if @options[:via] == :all
+
+ if !via_all && request_method_condition.empty?
+ msg = "You should not use the `match` method in your router without specifying an HTTP method.\n" \
+ "If you want to expose your action to GET, use `get` in the router:\n\n" \
+ " Instead of: match \"controller#action\"\n" \
+ " Do: get \"controller#action\""
+ raise msg
+ end
end
def to_route
@@ -263,7 +274,7 @@ module ActionDispatch
# of most Rails applications, this is beneficial.
def root(options = {})
options = { :to => options } if options.is_a?(String)
- match '/', { :as => :root }.merge(options)
+ match '/', { :as => :root, :via => :get }.merge(options)
end
# Matches a url pattern to one or more routes. Any symbols in a pattern
@@ -416,7 +427,7 @@ module ActionDispatch
options[:as] ||= app_name(app)
- match(path, options.merge(:to => app, :anchor => false, :format => false))
+ match(path, options.merge(:to => app, :anchor => false, :format => false, :via => :all))
define_generate_prefix(app, options[:as])
self
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 45075050eb..f1aa131cbb 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -96,7 +96,25 @@ module ActionDispatch
def initialize
@routes = {}
@helpers = []
- @module = Module.new
+ @module = Module.new do
+ protected
+
+ def handle_positional_args(args, options, route)
+ inner_options = args.extract_options!
+ result = options.dup
+
+ if args.any?
+ keys = route.segment_keys
+ if args.size < keys.size - 1 # take format into account
+ keys -= self.url_options.keys if self.respond_to?(:url_options)
+ keys -= options.keys
+ end
+ result.merge!(Hash[keys.zip(args)])
+ end
+
+ result.merge!(inner_options)
+ end
+ end
end
def helper_names
@@ -135,40 +153,37 @@ module ActionDispatch
end
private
- def url_helper_name(name, kind = :url)
- :"#{name}_#{kind}"
+ def url_helper_name(name, only_path)
+ if only_path
+ :"#{name}_path"
+ else
+ :"#{name}_url"
+ end
end
- def hash_access_name(name, kind = :url)
- :"hash_for_#{name}_#{kind}"
+ def hash_access_name(name, only_path)
+ if only_path
+ :"hash_for_#{name}_path"
+ else
+ :"hash_for_#{name}_url"
+ end
end
def define_named_route_methods(name, route)
- {:url => {:only_path => false}, :path => {:only_path => true}}.each do |kind, opts|
- hash = route.defaults.merge(:use_route => name).merge(opts)
- define_hash_access route, name, kind, hash
- define_url_helper route, name, kind, hash
+ [true, false].each do |only_path|
+ hash = route.defaults.merge(:use_route => name, :only_path => only_path)
+ define_hash_access route, name, hash
+ define_url_helper route, name, hash
end
end
- def define_hash_access(route, name, kind, options)
- selector = hash_access_name(name, kind)
+ def define_hash_access(route, name, options)
+ selector = hash_access_name(name, options[:only_path])
@module.module_eval do
- remove_possible_method selector
-
- define_method(selector) do |*args|
- inner_options = args.extract_options!
- result = options.dup
-
- if args.any?
- result[:_positional_args] = args
- result[:_positional_keys] = route.segment_keys
- end
-
- result.merge(inner_options)
+ redefine_method(selector) do |*args|
+ self.handle_positional_args(args, options, route)
end
-
protected selector
end
helpers << selector
@@ -187,9 +202,9 @@ module ActionDispatch
#
# foo_url(bar, baz, bang, :sort_by => 'baz')
#
- def define_url_helper(route, name, kind, options)
- selector = url_helper_name(name, kind)
- hash_access_method = hash_access_name(name, kind)
+ def define_url_helper(route, name, options)
+ selector = url_helper_name(name, options[:only_path])
+ hash_access_method = hash_access_name(name, options[:only_path])
if optimize_helper?(route)
@module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1
@@ -609,8 +624,6 @@ module ActionDispatch
def url_for(options)
options = default_url_options.merge(options || {})
- handle_positional_args(options)
-
user, password = extract_authentication(options)
path_segments = options.delete(:_path_segments)
script_name = options.delete(:script_name).presence || _generate_prefix(options)
@@ -680,16 +693,6 @@ module ActionDispatch
end
end
- def handle_positional_args(options)
- return unless args = options.delete(:_positional_args)
-
- keys = options.delete(:_positional_keys)
- keys -= options.keys if args.size < keys.size - 1 # take format into account
-
- # Tell url_for to skip default_url_options
- options.merge!(Hash[args.zip(keys).map { |v, k| [k, v] }])
- end
-
end
end
end