aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib')
-rw-r--r--actionpack/lib/abstract_controller/layouts.rb3
-rw-r--r--actionpack/lib/abstract_controller/url_for.rb1
-rw-r--r--actionpack/lib/action_controller.rb1
-rw-r--r--actionpack/lib/action_controller/caching/actions.rb2
-rw-r--r--actionpack/lib/action_controller/caching/pages.rb3
-rw-r--r--actionpack/lib/action_controller/log_subscriber.rb2
-rw-r--r--actionpack/lib/action_controller/metal.rb5
-rw-r--r--actionpack/lib/action_controller/metal/helpers.rb6
-rw-r--r--actionpack/lib/action_controller/metal/http_authentication.rb2
-rw-r--r--actionpack/lib/action_controller/metal/redirecting.rb6
-rw-r--r--actionpack/lib/action_controller/metal/renderers.rb2
-rw-r--r--actionpack/lib/action_controller/metal/url_for.rb18
-rw-r--r--actionpack/lib/action_controller/railtie.rb10
-rw-r--r--actionpack/lib/action_controller/test_case.rb14
-rw-r--r--actionpack/lib/action_controller/vendor/html-scanner/html/node.rb8
-rw-r--r--actionpack/lib/action_dispatch.rb1
-rw-r--r--actionpack/lib/action_dispatch/http/response.rb1
-rw-r--r--actionpack/lib/action_dispatch/http/url.rb4
-rw-r--r--actionpack/lib/action_dispatch/middleware/callbacks.rb8
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/abstract_store.rb4
-rw-r--r--actionpack/lib/action_dispatch/middleware/stack.rb9
-rw-r--r--actionpack/lib/action_dispatch/middleware/static.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb4
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb6
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb44
-rw-r--r--actionpack/lib/action_dispatch/routing/polymorphic_routes.rb10
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb43
-rw-r--r--actionpack/lib/action_dispatch/routing/url_for.rb5
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/routing.rb24
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/selector.rb8
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb37
-rw-r--r--actionpack/lib/action_dispatch/testing/test_request.rb3
-rw-r--r--actionpack/lib/action_dispatch/testing/test_response.rb22
-rw-r--r--actionpack/lib/action_view/base.rb3
-rw-r--r--actionpack/lib/action_view/helpers.rb1
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb30
-rw-r--r--actionpack/lib/action_view/helpers/date_helper.rb1
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb99
-rw-r--r--actionpack/lib/action_view/helpers/form_options_helper.rb10
-rw-r--r--actionpack/lib/action_view/helpers/form_tag_helper.rb4
-rw-r--r--actionpack/lib/action_view/helpers/text_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/url_helper.rb28
-rw-r--r--actionpack/lib/action_view/template/error.rb1
-rw-r--r--actionpack/lib/action_view/template/resolver.rb1
-rw-r--r--actionpack/lib/action_view/test_case.rb29
-rw-r--r--actionpack/lib/action_view/testing/resolvers.rb8
46 files changed, 286 insertions, 249 deletions
diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb
index 958e7f7ec8..b68c7d9216 100644
--- a/actionpack/lib/abstract_controller/layouts.rb
+++ b/actionpack/lib/abstract_controller/layouts.rb
@@ -347,8 +347,7 @@ module AbstractController
begin
layout_name = _layout if action_has_layout?
rescue NameError => e
- raise NoMethodError,
- "You specified #{@_layout.inspect} as the layout, but no such method was found"
+ raise e, "Could not render layout: #{e.message}"
end
if require_layout && action_has_layout? && !layout_name
diff --git a/actionpack/lib/abstract_controller/url_for.rb b/actionpack/lib/abstract_controller/url_for.rb
index 2e9de22ecd..e5d5bef6b4 100644
--- a/actionpack/lib/abstract_controller/url_for.rb
+++ b/actionpack/lib/abstract_controller/url_for.rb
@@ -1,7 +1,6 @@
module AbstractController
module UrlFor
extend ActiveSupport::Concern
-
include ActionDispatch::Routing::UrlFor
def _routes
diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb
index e02578eafd..5b81cd39f4 100644
--- a/actionpack/lib/action_controller.rb
+++ b/actionpack/lib/action_controller.rb
@@ -72,4 +72,5 @@ require 'active_support/core_ext/load_error'
require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/name_error'
+require 'active_support/core_ext/uri'
require 'active_support/inflector'
diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb
index a3591eafbe..d69d96b974 100644
--- a/actionpack/lib/action_controller/caching/actions.rb
+++ b/actionpack/lib/action_controller/caching/actions.rb
@@ -161,7 +161,7 @@ module ActionController #:nodoc:
def normalize!(path)
path << 'index' if path[-1] == ?/
path << ".#{extension}" if extension and !path.ends_with?(extension)
- URI.unescape(path)
+ URI.parser.unescape(path)
end
end
end
diff --git a/actionpack/lib/action_controller/caching/pages.rb b/actionpack/lib/action_controller/caching/pages.rb
index 4f7a5d3f55..df4d500069 100644
--- a/actionpack/lib/action_controller/caching/pages.rb
+++ b/actionpack/lib/action_controller/caching/pages.rb
@@ -1,5 +1,4 @@
require 'fileutils'
-require 'uri'
require 'active_support/core_ext/class/attribute_accessors'
module ActionController #:nodoc:
@@ -99,7 +98,7 @@ module ActionController #:nodoc:
private
def page_cache_file(path)
- name = (path.empty? || path == "/") ? "/index" : URI.unescape(path.chomp('/'))
+ name = (path.empty? || path == "/") ? "/index" : URI.parser.unescape(path.chomp('/'))
name << page_cache_extension unless (name.split('/').last || name).include? '.'
return name
end
diff --git a/actionpack/lib/action_controller/log_subscriber.rb b/actionpack/lib/action_controller/log_subscriber.rb
index ece270b3ce..3b19310a69 100644
--- a/actionpack/lib/action_controller/log_subscriber.rb
+++ b/actionpack/lib/action_controller/log_subscriber.rb
@@ -42,7 +42,7 @@ module ActionController
def #{method}(event)
key_or_path = event.payload[:key] || event.payload[:path]
human_name = #{method.to_s.humanize.inspect}
- info("\#{human_name} \#{key_or_path} (%.1fms)" % event.duration)
+ info("\#{human_name} \#{key_or_path} \#{"(%.1fms)" % event.duration}")
end
METHOD
end
diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb
index 96cb5977d5..ace1aabe03 100644
--- a/actionpack/lib/action_controller/metal.rb
+++ b/actionpack/lib/action_controller/metal.rb
@@ -85,6 +85,9 @@ module ActionController
def initialize(*)
@_headers = {"Content-Type" => "text/html"}
@_status = 200
+ @_request = nil
+ @_response = nil
+ @_routes = nil
super
end
@@ -99,7 +102,7 @@ module ActionController
# Basic implementations for content_type=, location=, and headers are
# provided to reduce the dependency on the RackDelegation module
# in Renderer and Redirector.
-
+
def content_type=(type)
headers["Content-Type"] = type.to_s
end
diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb
index 4d5d534c75..d14831b763 100644
--- a/actionpack/lib/action_controller/metal/helpers.rb
+++ b/actionpack/lib/action_controller/metal/helpers.rb
@@ -96,9 +96,9 @@ module ActionController
def all_helpers_from_path(path)
helpers = []
- Array.wrap(path).each do |path|
- extract = /^#{Regexp.quote(path.to_s)}\/?(.*)_helper.rb$/
- helpers += Dir["#{path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1') }
+ Array.wrap(path).each do |_path|
+ extract = /^#{Regexp.quote(_path.to_s)}\/?(.*)_helper.rb$/
+ helpers += Dir["#{_path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1') }
end
helpers.sort!
helpers.uniq!
diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb
index 251b1a8a8b..6a7e170306 100644
--- a/actionpack/lib/action_controller/metal/http_authentication.rb
+++ b/actionpack/lib/action_controller/metal/http_authentication.rb
@@ -417,7 +417,7 @@ module ActionController
# Authorization: Token token="abc", nonce="def"
# Then the returned token is "abc", and the options is {:nonce => "def"}
#
- # request - ActionController::Request instance with the current headers.
+ # request - ActionDispatch::Request instance with the current headers.
#
# Returns an Array of [String, Hash] if a token is present.
# Returns nil if no token is found.
diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb
index 10d7794b57..55c650df6c 100644
--- a/actionpack/lib/action_controller/metal/redirecting.rb
+++ b/actionpack/lib/action_controller/metal/redirecting.rb
@@ -20,6 +20,7 @@ module ActionController
# * <tt>Record</tt> - The URL will be generated by calling url_for with the +options+, which will reference a named URL for that record.
# * <tt>String</tt> starting with <tt>protocol://</tt> (like <tt>http://</tt>) - Is passed straight through as the target for redirection.
# * <tt>String</tt> not containing a protocol - The current protocol and host is prepended to the string.
+ # * <tt>Proc</tt> - A block that will be executed in the controller's context. Should return any option accepted by +redirect_to+.
# * <tt>:back</tt> - Back to the page that issued the request. Useful for forms that are triggered from multiple places.
# Short-hand for <tt>redirect_to(request.env["HTTP_REFERER"])</tt>
#
@@ -30,6 +31,7 @@ module ActionController
# redirect_to "/images/screenshot.jpg"
# redirect_to articles_url
# redirect_to :back
+ # redirect_to proc { edit_post_url(@post) }
#
# The redirection happens as a "302 Moved" header unless otherwise specified.
#
@@ -38,7 +40,7 @@ module ActionController
# redirect_to :action=>'atom', :status => :moved_permanently
# redirect_to post_url(@post), :status => 301
# redirect_to :action=>'atom', :status => 302
- #
+ #
# The status code can either be a standard {HTTP Status code}[http://www.iana.org/assignments/http-status-codes] as an
# integer, or a symbol representing the downcased, underscored and symbolized description.
#
@@ -85,6 +87,8 @@ module ActionController
when :back
raise RedirectBackError unless refer = request.headers["Referer"]
refer
+ when Proc
+ _compute_redirect_to_location options.call
else
url_for(options)
end.gsub(/[\r\n]/, '')
diff --git a/actionpack/lib/action_controller/metal/renderers.rb b/actionpack/lib/action_controller/metal/renderers.rb
index 0be07cd1fc..f9b226b7c9 100644
--- a/actionpack/lib/action_controller/metal/renderers.rb
+++ b/actionpack/lib/action_controller/metal/renderers.rb
@@ -71,7 +71,7 @@ module ActionController
end
add :json do |json, options|
- json = ActiveSupport::JSON.encode(json, options) unless json.respond_to?(:to_str)
+ json = json.to_json(options) unless json.respond_to?(:to_str)
json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
self.content_type ||= Mime::JSON
self.response_body = json
diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb
index 85c6b0a9b5..333eeaeffb 100644
--- a/actionpack/lib/action_controller/metal/url_for.rb
+++ b/actionpack/lib/action_controller/metal/url_for.rb
@@ -5,16 +5,20 @@ module ActionController
include AbstractController::UrlFor
def url_options
- options = {}
- if _routes.equal?(env["action_dispatch.routes"])
- options[:script_name] = request.script_name.dup
- end
-
- super.merge(options).reverse_merge(
+ @_url_options ||= super.reverse_merge(
:host => request.host_with_port,
:protocol => request.protocol,
:_path_segments => request.symbolized_path_parameters
- )
+ ).freeze
+
+ if _routes.equal?(env["action_dispatch.routes"])
+ @_url_options.dup.tap do |options|
+ options[:script_name] = request.script_name.dup
+ options.freeze
+ end
+ else
+ @_url_options
+ end
end
end
end
diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb
index aea28d9265..0ade42ba2d 100644
--- a/actionpack/lib/action_controller/railtie.rb
+++ b/actionpack/lib/action_controller/railtie.rb
@@ -26,6 +26,10 @@ module ActionController
options.stylesheets_dir ||= paths.public.stylesheets.to_a.first
options.page_cache_directory ||= paths.public.to_a.first
+ # make sure readers methods get compiled
+ options.asset_path ||= nil
+ options.asset_host ||= nil
+
ActiveSupport.on_load(:action_controller) do
include app.routes.mounted_helpers
extend ::AbstractController::Railties::RoutesHelpers.with(app.routes)
@@ -33,5 +37,11 @@ module ActionController
options.each { |k,v| send("#{k}=", v) }
end
end
+
+ initializer "action_controller.compile_config_methods" do
+ ActiveSupport.on_load(:action_controller) do
+ config.compile_methods! if config.respond_to?(:compile_methods!)
+ end
+ end
end
end
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index 065152d01d..70a5de7f30 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -127,7 +127,7 @@ module ActionController
class Result < ::Array #:nodoc:
def to_s() join '/' end
def self.new_escaped(strings)
- new strings.collect {|str| URI.unescape str}
+ new strings.collect {|str| uri_parser.unescape str}
end
end
@@ -200,7 +200,7 @@ module ActionController
# Superclass for ActionController functional tests. Functional tests allow you to
# test a single controller action per test method. This should not be confused with
- # integration tests (see ActionController::IntegrationTest), which are more like
+ # integration tests (see ActionDispatch::IntegrationTest), which are more like
# "stories" that can involve multiple controllers and multiple actions (i.e. multiple
# different HTTP requests).
#
@@ -417,7 +417,7 @@ module ActionController
@request.env.delete('PATH_INFO')
- if @controller
+ if defined?(@controller) && @controller
@controller.request = @request
@controller.params = {}
end
@@ -462,9 +462,11 @@ module ActionController
# The exception is stored in the exception accessor for further inspection.
module RaiseActionExceptions
def self.included(base)
- base.class_eval do
- attr_accessor :exception
- protected :exception, :exception=
+ unless base.method_defined?(:exception) && base.method_defined?(:exception=)
+ base.class_eval do
+ attr_accessor :exception
+ protected :exception, :exception=
+ end
end
end
diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb
index 85250721e7..22b3243104 100644
--- a/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb
+++ b/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb
@@ -18,14 +18,14 @@ module HTML #:nodoc:
hash[k] = Conditions.new(v)
when :children
hash[k] = v = keys_to_symbols(v)
- v.each do |k,v2|
- case k
+ v.each do |key,value|
+ case key
when :count, :greater_than, :less_than
# keys are valid, and require no further processing
when :only
- v[k] = Conditions.new(v2)
+ v[key] = Conditions.new(value)
else
- raise "illegal key #{k.inspect} => #{v2.inspect}"
+ raise "illegal key #{key.inspect} => #{value.inspect}"
end
end
else
diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb
index aeec934be8..50faf666e6 100644
--- a/actionpack/lib/action_dispatch.rb
+++ b/actionpack/lib/action_dispatch.rb
@@ -85,6 +85,7 @@ module ActionDispatch
autoload_under 'testing' do
autoload :Assertions
autoload :Integration
+ autoload :IntegrationTest, 'action_dispatch/testing/integration'
autoload :PerformanceTest
autoload :TestProcess
autoload :TestRequest
diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb
index ff5e96fdf7..151c90167b 100644
--- a/actionpack/lib/action_dispatch/http/response.rb
+++ b/actionpack/lib/action_dispatch/http/response.rb
@@ -140,7 +140,6 @@ module ActionDispatch # :nodoc:
assign_default_content_type_and_charset!
handle_conditional_get!
self["Set-Cookie"] = self["Set-Cookie"].join("\n") if self["Set-Cookie"].respond_to?(:join)
- self["ETag"] = @_etag if @_etag
super
end
diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb
index 2e39d0dbc2..3e5cd6a2f9 100644
--- a/actionpack/lib/action_dispatch/http/url.rb
+++ b/actionpack/lib/action_dispatch/http/url.rb
@@ -15,12 +15,12 @@ module ActionDispatch
# Returns 'https://' if this is an SSL request and 'http://' otherwise.
def protocol
- ssl? ? 'https://' : 'http://'
+ @protocol ||= ssl? ? 'https://' : 'http://'
end
# Is this an SSL request?
def ssl?
- @env['HTTPS'] == 'on' || @env['HTTP_X_FORWARDED_PROTO'] == 'https'
+ @ssl ||= @env['HTTPS'] == 'on' || @env['HTTP_X_FORWARDED_PROTO'] == 'https'
end
# Returns the \host for this request, such as "example.com".
diff --git a/actionpack/lib/action_dispatch/middleware/callbacks.rb b/actionpack/lib/action_dispatch/middleware/callbacks.rb
index e4ae480bfb..0bb950d1cc 100644
--- a/actionpack/lib/action_dispatch/middleware/callbacks.rb
+++ b/actionpack/lib/action_dispatch/middleware/callbacks.rb
@@ -19,9 +19,11 @@ module ActionDispatch
# replace the existing callback. Passing an identifier is a suggested
# practice if the code adding a preparation block may be reloaded.
def self.to_prepare(*args, &block)
- if args.first.is_a?(Symbol) && block_given?
- define_method :"__#{args.first}", &block
- set_callback(:prepare, :"__#{args.first}")
+ first_arg = args.first
+ if first_arg.is_a?(Symbol) && block_given?
+ remove_method :"__#{first_arg}" if method_defined?(:"__#{first_arg}")
+ define_method :"__#{first_arg}", &block
+ set_callback(:prepare, :"__#{first_arg}")
else
set_callback(:prepare, *args, &block)
end
diff --git a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
index 348a2d1eb2..ea49b30630 100644
--- a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
+++ b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
@@ -102,8 +102,8 @@ module ActionDispatch
def destroy
clear
- @by.send(:destroy, @env) if @by
- @env[ENV_SESSION_OPTIONS_KEY][:id] = nil if @env && @env[ENV_SESSION_OPTIONS_KEY]
+ @by.send(:destroy, @env) if defined?(@by) && @by
+ @env[ENV_SESSION_OPTIONS_KEY][:id] = nil if defined?(@env) && @env && @env[ENV_SESSION_OPTIONS_KEY]
@loaded = false
end
diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb
index db7f342bc5..e3cd779756 100644
--- a/actionpack/lib/action_dispatch/middleware/stack.rb
+++ b/actionpack/lib/action_dispatch/middleware/stack.rb
@@ -41,9 +41,12 @@ module ActionDispatch
end
end
- def initialize(*args, &block)
- super(*args)
- block.call(self) if block_given?
+ # Use this instead of super to work around a warning.
+ alias :array_initialize :initialize
+
+ def initialize(*args)
+ array_initialize(*args)
+ yield(self) if block_given?
end
def insert(index, *args, &block)
diff --git a/actionpack/lib/action_dispatch/middleware/static.rb b/actionpack/lib/action_dispatch/middleware/static.rb
index 581cadbeb4..cf13938331 100644
--- a/actionpack/lib/action_dispatch/middleware/static.rb
+++ b/actionpack/lib/action_dispatch/middleware/static.rb
@@ -4,7 +4,7 @@ module ActionDispatch
class FileHandler
def initialize(at, root)
@at, @root = at.chomp('/'), root.chomp('/')
- @compiled_at = Regexp.compile(/^#{Regexp.escape(at)}/) unless @at.blank?
+ @compiled_at = (Regexp.compile(/^#{Regexp.escape(at)}/) unless @at.blank?)
@compiled_root = Regexp.compile(/^#{Regexp.escape(root)}/)
@file_server = ::Rack::File.new(root)
end
diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb
index e963b04524..97f7cf0bbe 100644
--- a/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb
+++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb
@@ -14,7 +14,7 @@
def debug_hash(hash)
hash.sort_by { |k, v| k.to_s }.map { |k, v| "#{k}: #{v.inspect rescue $!.message}" }.join("\n")
- end
+ end unless self.class.method_defined?(:debug_hash)
%>
<h2 style="margin-top: 30px">Request</h2>
@@ -28,4 +28,4 @@
<h2 style="margin-top: 30px">Response</h2>
-<p><b>Headers</b>: <pre><%=h @response ? @response.headers.inspect.gsub(',', ",\n") : 'None' %></pre></p>
+<p><b>Headers</b>: <pre><%=h defined?(@response) ? @response.headers.inspect.gsub(',', ",\n") : 'None' %></pre></p>
diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb
index d18b162a93..8771b5fd6d 100644
--- a/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb
+++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.erb
@@ -12,14 +12,14 @@
<div id="traces">
<% names.each do |name| %>
<%
- show = "document.getElementById('#{name.gsub /\s/, '-'}').style.display='block';"
- hide = (names - [name]).collect {|hide_name| "document.getElementById('#{hide_name.gsub /\s/, '-'}').style.display='none';"}
+ show = "document.getElementById('#{name.gsub(/\s/, '-')}').style.display='block';"
+ hide = (names - [name]).collect {|hide_name| "document.getElementById('#{hide_name.gsub(/\s/, '-')}').style.display='none';"}
%>
<a href="#" onclick="<%= hide.join %><%= show %>; return false;"><%= name %></a> <%= '|' unless names.last == name %>
<% end %>
<% traces.each do |name, trace| %>
- <div id="<%= name.gsub /\s/, '-' %>" style="display: <%= name == "Application Trace" ? 'block' : 'none' %>;">
+ <div id="<%= name.gsub(/\s/, '-') %>" style="display: <%= (name == "Application Trace") ? 'block' : 'none' %>;">
<pre><code><%=h trace.join "\n" %></code></pre>
</div>
<% end %>
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index fe85acb94e..0cb02c5b80 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -62,7 +62,6 @@ module ActionDispatch
if using_match_shorthand?(path_without_format, @options)
to_shorthand = @options[:to].blank?
@options[:to] ||= path_without_format[1..-1].sub(%r{/([^/]*)$}, '#\1')
- @options[:as] ||= Mapper.normalize_name(path_without_format)
end
@options.merge!(default_controller_and_action(to_shorthand))
@@ -350,7 +349,7 @@ module ActionDispatch
options = args.last.is_a?(Hash) ? args.pop : {}
path = args.shift || block
- path_proc = path.is_a?(Proc) ? path : proc { |params| path % params }
+ path_proc = path.is_a?(Proc) ? path : proc { |params| params.empty? ? path : (path % params) }
status = options[:status] || 301
lambda do |env|
@@ -395,10 +394,10 @@ module ActionDispatch
# namespace "admin" do
# resources :posts, :comments
# end
- #
+ #
# This will create a number of routes for each of the posts and comments
# controller. For Admin::PostsController, Rails will create:
- #
+ #
# GET /admin/photos
# GET /admin/photos/new
# POST /admin/photos
@@ -406,33 +405,33 @@ module ActionDispatch
# GET /admin/photos/1/edit
# PUT /admin/photos/1
# DELETE /admin/photos/1
- #
+ #
# If you want to route /photos (without the prefix /admin) to
# Admin::PostsController, you could use
- #
+ #
# scope :module => "admin" do
# resources :posts, :comments
# end
#
# or, for a single case
- #
+ #
# resources :posts, :module => "admin"
- #
+ #
# If you want to route /admin/photos to PostsController
# (without the Admin:: module prefix), you could use
- #
+ #
# scope "/admin" do
# resources :posts, :comments
# end
#
# or, for a single case
- #
+ #
# resources :posts, :path => "/admin"
#
# In each of these cases, the named routes remain the same as if you did
# not use scope. In the last case, the following paths map to
# PostsController:
- #
+ #
# GET /admin/photos
# GET /admin/photos/new
# POST /admin/photos
@@ -676,6 +675,7 @@ module ActionDispatch
DEFAULT_ACTIONS = [:show, :create, :update, :destroy, :new, :edit]
def initialize(entities, options)
+ @as = nil
@name = entities.to_s
@path = (options.delete(:path) || @name).to_s
@controller = (options.delete(:controller) || plural).to_s
@@ -923,9 +923,14 @@ module ActionDispatch
if action.to_s =~ /^[\w\/]+$/
options[:action] ||= action unless action.to_s.include?("/")
- options[:as] = name_for_action(action, options[:as])
else
- options[:as] = name_for_action(options[:as])
+ action = nil
+ end
+
+ if options.key?(:as) && !options[:as]
+ options.delete(:as)
+ else
+ options[:as] = name_for_action(options[:as], action)
end
super(path, options)
@@ -1091,18 +1096,16 @@ module ActionDispatch
path || @scope[:path_names][name.to_sym] || name.to_s
end
- def prefix_name_for_action(action, as)
- if as.present?
+ def prefix_name_for_action(as, action)
+ if as
as.to_s
- elsif as
- nil
elsif !canonical_action?(action, @scope[:scope_level])
action.to_s
end
end
- def name_for_action(action, as=nil)
- prefix = prefix_name_for_action(action, as)
+ def name_for_action(as, action)
+ prefix = prefix_name_for_action(as, action)
prefix = Mapper.normalize_name(prefix) if prefix
name_prefix = @scope[:as]
@@ -1126,7 +1129,8 @@ module ActionDispatch
[name_prefix, member_name, prefix]
end
- name.select(&:present?).join("_").presence
+ candidate = name.select(&:present?).join("_").presence
+ candidate unless as.nil? && @set.routes.map(&:name).include?(candidate)
end
end
diff --git a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
index 02ba5236ee..49e237f8db 100644
--- a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
+++ b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
@@ -105,7 +105,7 @@ module ActionDispatch
else [ record_or_hash_or_array ]
end
- inflection = if options[:action].to_s == "new"
+ inflection = if options[:action] && options[:action].to_s == "new"
args.pop
:singular
elsif (record.respond_to?(:persisted?) && !record.persisted?)
@@ -168,10 +168,7 @@ module ActionDispatch
end
def build_named_route_call(records, inflection, options = {})
- unless records.is_a?(Array)
- record = extract_record(records)
- route = []
- else
+ if records.is_a?(Array)
record = records.pop
route = records.map do |parent|
if parent.is_a?(Symbol) || parent.is_a?(String)
@@ -180,6 +177,9 @@ module ActionDispatch
ActiveModel::Naming.route_key(parent).singularize
end
end
+ else
+ record = extract_record(records)
+ route = []
end
if record.is_a?(Symbol) || record.is_a?(String)
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 1a5f21bd09..5d18dfe369 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -66,7 +66,7 @@ module ActionDispatch
end
def split_glob_param!(params)
- params[@glob_param] = params[@glob_param].split('/').map { |v| URI.unescape(v) }
+ params[@glob_param] = params[@glob_param].split('/').map { |v| URI.parser.unescape(v) }
end
end
@@ -157,6 +157,7 @@ module ActionDispatch
# We use module_eval to avoid leaks
@module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1
+ remove_method :#{selector} if method_defined?(:#{selector})
def #{selector}(*args)
options = args.extract_options!
@@ -190,6 +191,7 @@ module ActionDispatch
hash_access_method = hash_access_name(name, kind)
@module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1
+ remove_method :#{selector} if method_defined?(:#{selector})
def #{selector}(*args)
url_for(#{hash_access_method}(*args))
end
@@ -300,9 +302,9 @@ module ActionDispatch
extend ActiveSupport::Concern
include UrlFor
- @routes = routes
+ @_routes = routes
class << self
- delegate :url_for, :to => '@routes'
+ delegate :url_for, :to => '@_routes'
end
extend routes.named_routes.module
@@ -311,7 +313,7 @@ module ActionDispatch
# Yes plz - JP
included do
routes.install_helpers(self)
- singleton_class.send(:define_method, :_routes) { routes }
+ singleton_class.send(:redefine_method, :_routes) { routes }
end
define_method(:_routes) { @_routes || routes }
@@ -334,6 +336,19 @@ module ActionDispatch
end
class Generator #:nodoc:
+ PARAMETERIZE = {
+ :parameterize => lambda do |name, value|
+ if name == :controller
+ value
+ elsif value.is_a?(Array)
+ value.map { |v| Rack::Mount::Utils.escape_uri(v.to_param) }.join('/')
+ else
+ return nil unless param = value.to_param
+ param.split('/').map { |v| Rack::Mount::Utils.escape_uri(v) }.join("/")
+ end
+ end
+ }
+
attr_reader :options, :recall, :set, :named_route
def initialize(options, recall, set, extras = false)
@@ -422,7 +437,7 @@ module ActionDispatch
end
def generate
- path, params = @set.set.generate(:path_info, named_route, options, recall, opts)
+ path, params = @set.set.generate(:path_info, named_route, options, recall, PARAMETERIZE)
raise_routing_error unless path
@@ -430,26 +445,12 @@ module ActionDispatch
return [path, params.keys] if @extras
- path << "?#{params.to_query}" if params.any?
+ path << "?#{params.to_query}" unless params.empty?
path
rescue Rack::Mount::RoutingError
raise_routing_error
end
- def opts
- parameterize = lambda do |name, value|
- if name == :controller
- value
- elsif value.is_a?(Array)
- value.map { |v| Rack::Mount::Utils.escape_uri(v.to_param) }.join('/')
- else
- return nil unless param = value.to_param
- param.split('/').map { |v| Rack::Mount::Utils.escape_uri(v) }.join("/")
- end
- end
- {:parameterize => parameterize}
- end
-
def raise_routing_error
raise ActionController::RoutingError.new("No route matches #{options.inspect}")
end
@@ -543,7 +544,7 @@ module ActionDispatch
params.each do |key, value|
if value.is_a?(String)
value = value.dup.force_encoding(Encoding::BINARY) if value.encoding_aware?
- params[key] = URI.unescape(value)
+ params[key] = URI.parser.unescape(value)
end
end
diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb
index e836cf7c8e..bfdea41f60 100644
--- a/actionpack/lib/action_dispatch/routing/url_for.rb
+++ b/actionpack/lib/action_dispatch/routing/url_for.rb
@@ -98,6 +98,11 @@ module ActionDispatch
end
end
+ def initialize(*)
+ @_routes = nil
+ super
+ end
+
def url_options
default_url_options
end
diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
index c5fed1fc8f..1390b74a95 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
@@ -146,16 +146,16 @@ module ActionDispatch
#
def with_routing
old_routes, @routes = @routes, ActionDispatch::Routing::RouteSet.new
- old_controller, @controller = @controller, @controller.clone if @controller
- _routes = @routes
-
- # Unfortunately, there is currently an abstraction leak between AC::Base
- # and AV::Base which requires having the URL helpers in both AC and AV.
- # To do this safely at runtime for tests, we need to bump up the helper serial
- # to that the old AV subclass isn't cached.
- #
- # TODO: Make this unnecessary
- if @controller
+ if defined?(@controller) && @controller
+ old_controller, @controller = @controller, @controller.clone
+ _routes = @routes
+
+ # Unfortunately, there is currently an abstraction leak between AC::Base
+ # and AV::Base which requires having the URL helpers in both AC and AV.
+ # To do this safely at runtime for tests, we need to bump up the helper serial
+ # to that the old AV subclass isn't cached.
+ #
+ # TODO: Make this unnecessary
@controller.singleton_class.send(:include, _routes.url_helpers)
@controller.view_context_class = Class.new(@controller.view_context_class) do
include _routes.url_helpers
@@ -164,14 +164,14 @@ module ActionDispatch
yield @routes
ensure
@routes = old_routes
- if @controller
+ if defined?(@controller) && @controller
@controller = old_controller
end
end
# ROUTES TODO: These assertions should really work in an integration context
def method_missing(selector, *args, &block)
- if @controller && @routes && @routes.named_routes.helpers.include?(selector)
+ if defined?(@controller) && @controller && @routes && @routes.named_routes.helpers.include?(selector)
@controller.send(selector, *args, &block)
else
super
diff --git a/actionpack/lib/action_dispatch/testing/assertions/selector.rb b/actionpack/lib/action_dispatch/testing/assertions/selector.rb
index e1015c62cd..2b862fb7d6 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/selector.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/selector.rb
@@ -67,7 +67,7 @@ module ActionDispatch
arg = args.shift
elsif arg == nil
raise ArgumentError, "First argument is either selector or element to select, but nil found. Perhaps you called assert_select with an element that does not exist?"
- elsif @selected
+ elsif defined?(@selected) && @selected
matches = []
@selected.each do |selected|
@@ -187,6 +187,7 @@ module ActionDispatch
def assert_select(*args, &block)
# Start with optional element followed by mandatory selector.
arg = args.shift
+ @selected ||= nil
if arg.is_a?(HTML::Node)
# First argument is a node (tag or text, but also HTML root),
@@ -442,6 +443,7 @@ module ActionDispatch
assert_block("") { true } # to count the assertion
if block_given? && !([:remove, :show, :hide, :toggle].include? rjs_type)
begin
+ @selected ||= nil
in_scope, @selected = @selected, matches
yield matches
ensure
@@ -513,8 +515,8 @@ module ActionDispatch
node.content.gsub(/<!\[CDATA\[(.*)(\]\]>)?/m) { Rack::Utils.escapeHTML($1) }
end
- selected = elements.map do |element|
- text = element.children.select{ |c| not c.tag? }.map{ |c| fix_content[c] }.join
+ selected = elements.map do |_element|
+ text = _element.children.select{ |c| not c.tag? }.map{ |c| fix_content[c] }.join
root = HTML::Document.new(CGI.unescapeHTML("<encoded>#{text}</encoded>")).root
css_select(root, "encoded:root", &block)[0]
end
diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb
index a681c9a5b6..fee8cad9f5 100644
--- a/actionpack/lib/action_dispatch/testing/integration.rb
+++ b/actionpack/lib/action_dispatch/testing/integration.rb
@@ -171,6 +171,7 @@ module ActionDispatch
# Create and initialize a new Session instance.
def initialize(app)
+ super()
@app = app
# If the app is a Rails app, make url_helpers available on the session
@@ -182,6 +183,7 @@ module ActionDispatch
reset!
end
+ remove_method :default_url_options
def default_url_options
{ :host => host, :protocol => https? ? "https" : "http" }
end
@@ -257,19 +259,19 @@ module ActionDispatch
end
end
- port = host.split(':')[1]
+ hostname, port = host.split(':')
env = {
:method => method,
:params => parameters,
- "SERVER_NAME" => host.split(':')[0],
- "SERVER_PORT" => (port ? port : (https? ? "443" : "80")),
+ "SERVER_NAME" => hostname,
+ "SERVER_PORT" => port || (https? ? "443" : "80"),
"HTTPS" => https? ? "on" : "off",
"rack.url_scheme" => https? ? "https" : "http",
"REQUEST_URI" => path,
- "HTTP_HOST" => [host, port].compact.join(':'),
+ "HTTP_HOST" => host,
"REMOTE_ADDR" => remote_addr,
"CONTENT_TYPE" => "application/x-www-form-urlencoded",
"HTTP_ACCEPT" => accept
@@ -307,7 +309,7 @@ module ActionDispatch
include ActionDispatch::Assertions
def app
- @app
+ @app ||= nil
end
# Reset the current session. This is useful for testing multiple sessions
@@ -319,10 +321,10 @@ module ActionDispatch
%w(get post put head delete cookies assigns
xml_http_request xhr get_via_redirect post_via_redirect).each do |method|
define_method(method) do |*args|
- reset! unless @integration_session
+ reset! unless integration_session
# reset the html_document variable, but only for new get/post calls
@html_document = nil unless %w(cookies assigns).include?(method)
- @integration_session.__send__(method, *args).tap do
+ integration_session.__send__(method, *args).tap do
copy_session_variables!
end
end
@@ -347,7 +349,7 @@ module ActionDispatch
# Copy the instance variables from the current session instance into the
# test instance.
def copy_session_variables! #:nodoc:
- return unless @integration_session
+ return unless integration_session
%w(controller response request).each do |var|
instance_variable_set("@#{var}", @integration_session.__send__(var))
end
@@ -357,21 +359,26 @@ module ActionDispatch
include ActionDispatch::Routing::UrlFor
def url_options
- reset! unless @integration_session
- @integration_session.url_options
+ reset! unless integration_session
+ integration_session.url_options
end
# Delegate unhandled messages to the current session instance.
def method_missing(sym, *args, &block)
- reset! unless @integration_session
- if @integration_session.respond_to?(sym)
- @integration_session.__send__(sym, *args, &block).tap do
+ reset! unless integration_session
+ if integration_session.respond_to?(sym)
+ integration_session.__send__(sym, *args, &block).tap do
copy_session_variables!
end
else
super
end
end
+
+ private
+ def integration_session
+ @integration_session ||= nil
+ end
end
end
@@ -385,7 +392,7 @@ module ActionDispatch
#
# require "test_helper"
#
- # class ExampleTest < ActionController::IntegrationTest
+ # class ExampleTest < ActionDispatch::IntegrationTest
# fixtures :people
#
# def test_login
@@ -409,7 +416,7 @@ module ActionDispatch
#
# require "test_helper"
#
- # class AdvancedTest < ActionController::IntegrationTest
+ # class AdvancedTest < ActionDispatch::IntegrationTest
# fixtures :people, :rooms
#
# def test_login_and_speak
diff --git a/actionpack/lib/action_dispatch/testing/test_request.rb b/actionpack/lib/action_dispatch/testing/test_request.rb
index c587a36930..cf440a1fad 100644
--- a/actionpack/lib/action_dispatch/testing/test_request.rb
+++ b/actionpack/lib/action_dispatch/testing/test_request.rb
@@ -13,6 +13,7 @@ module ActionDispatch
env = Rails.application.env_config.merge(env) if defined?(Rails.application)
super(DEFAULT_ENV.merge(env))
+ @cookies = nil
self.host = 'test.host'
self.remote_addr = '0.0.0.0'
self.user_agent = 'Rails Testing'
@@ -66,7 +67,7 @@ module ActionDispatch
def accept=(mime_types)
@env.delete('action_dispatch.request.accepts')
- @env['HTTP_ACCEPT'] = Array(mime_types).collect { |mime_types| mime_types.to_s }.join(",")
+ @env['HTTP_ACCEPT'] = Array(mime_types).collect { |mime_type| mime_type.to_s }.join(",")
end
def cookies
diff --git a/actionpack/lib/action_dispatch/testing/test_response.rb b/actionpack/lib/action_dispatch/testing/test_response.rb
index 926034762f..82039e72e7 100644
--- a/actionpack/lib/action_dispatch/testing/test_response.rb
+++ b/actionpack/lib/action_dispatch/testing/test_response.rb
@@ -15,29 +15,15 @@ module ActionDispatch
end
# Was the response successful?
- def success?
- (200..299).include?(response_code)
- end
+ alias_method :success?, :successful?
# Was the URL not found?
- def missing?
- response_code == 404
- end
+ alias_method :missing?, :not_found?
# Were we redirected?
- def redirect?
- (300..399).include?(response_code)
- end
+ alias_method :redirect?, :redirection?
# Was there a server-side error?
- def error?
- (500..599).include?(response_code)
- end
- alias_method :server_error?, :error?
-
- # Was there a client client?
- def client_error?
- (400..499).include?(response_code)
- end
+ alias_method :error?, :server_error?
end
end
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index 3fa46d0f43..0bef3e3a08 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -209,8 +209,7 @@ module ActionView #:nodoc:
@_request = controller.request if controller.respond_to?(:request)
end
- config = controller && controller.respond_to?(:config) ? controller.config : {}
- @_config = ActiveSupport::InheritableOptions.new(config)
+ @_config = controller && controller.respond_to?(:config) ? controller.config.inheritable_copy : {}
@_content_for = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new }
@_virtual_path = nil
diff --git a/actionpack/lib/action_view/helpers.rb b/actionpack/lib/action_view/helpers.rb
index b7ffa345cc..41013c800c 100644
--- a/actionpack/lib/action_view/helpers.rb
+++ b/actionpack/lib/action_view/helpers.rb
@@ -12,7 +12,6 @@ module ActionView #:nodoc:
autoload :CsrfHelper
autoload :DateHelper
autoload :DebugHelper
- autoload :DeprecatedBlockHelpers
autoload :FormHelper
autoload :FormOptionsHelper
autoload :FormTagHelper
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index 687cb83d75..c1dfbe5dc3 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -705,19 +705,29 @@ module ActionView
private
- def rewrite_extension?(source, dir, ext)
- source_ext = File.extname(source)[1..-1]
- ext && (source_ext.blank? || (ext != source_ext && File.exist?(File.join(config.assets_dir, dir, "#{source}.#{ext}"))))
+ def rewrite_extension(source, dir, ext)
+ source_ext = File.extname(source)
+
+ if source_ext.empty?
+ "#{source}.#{ext}"
+ elsif ext != source_ext[1..-1]
+ with_ext = "#{source}.#{ext}"
+ with_ext if File.exist?(File.join(config.assets_dir, dir, with_ext))
+ end || source
end
def rewrite_host_and_protocol(source, has_request)
host = compute_asset_host(source)
- if has_request && host.present? && !is_uri?(host)
+ if has_request && host && !is_uri?(host)
host = "#{controller.request.protocol}#{host}"
end
"#{host}#{source}"
end
+ def rewrite_relative_url_root(source, relative_url_root)
+ relative_url_root && !source.starts_with?("#{relative_url_root}/") ? "#{relative_url_root}#{source}" : source
+ end
+
# Add the the extension +ext+ if not present. Return full URLs otherwise untouched.
# Prefix with <tt>/dir/</tt> if lacking a leading +/+. Account for relative URL
# roots. Rewrite the asset path for cache-busting asset ids. Include
@@ -725,17 +735,15 @@ module ActionView
def compute_public_path(source, dir, ext = nil, include_host = true)
return source if is_uri?(source)
- source += ".#{ext}" if rewrite_extension?(source, dir, ext)
- source = "/#{dir}/#{source}" unless source[0] == ?/
+ source = rewrite_extension(source, dir, ext) if ext
+ source = "/#{dir}/#{source}" unless source[0] == ?/
if controller.respond_to?(:env) && controller.env["action_dispatch.asset_path"]
source = rewrite_asset_path(source, controller.env["action_dispatch.asset_path"])
end
source = rewrite_asset_path(source, config.asset_path)
has_request = controller.respond_to?(:request)
- if has_request && include_host && source !~ %r{^#{controller.config.relative_url_root}/}
- source = "#{controller.config.relative_url_root}#{source}"
- end
+ source = rewrite_relative_url_root(source, controller.config.relative_url_root) if has_request && include_host
source = rewrite_host_and_protocol(source, has_request) if include_host
source
@@ -802,10 +810,10 @@ module ActionView
end
asset_id = rails_asset_id(source)
- if asset_id.blank?
+ if asset_id.empty?
source
else
- source + "?#{asset_id}"
+ "#{source}?#{asset_id}"
end
end
diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb
index 9891478606..3aee4fb773 100644
--- a/actionpack/lib/action_view/helpers/date_helper.rb
+++ b/actionpack/lib/action_view/helpers/date_helper.rb
@@ -923,6 +923,7 @@ module ActionView
private
def datetime_selector(options, html_options)
datetime = value(object) || default_datetime(options)
+ @auto_index ||= nil
options = options.dup
options[:field_name] = @method_name
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 0937075edf..c47fac05ef 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -293,34 +293,27 @@ module ActionView
#
# If you don't need to attach a form to a model instance, then check out
# FormTagHelper#form_tag.
- def form_for(record, record_object = nil, options = nil, &proc)
+ def form_for(record, options = nil, &proc)
raise ArgumentError, "Missing block" unless block_given?
- options, record_object = record_object, nil if record_object.is_a?(Hash)
options ||= {}
+ options[:html] ||= {}
case record
when String, Symbol
- ActiveSupport::Deprecation.warn("Using form_for(:name, @resource) is deprecated. Please use form_for(@resource, :as => :name) instead.", caller) if record_object
object_name = record
- object = record_object
- when Array
- object = record.last
- object_name = options[:as] || ActiveModel::Naming.param_key(object)
- apply_form_for_options!(record, options)
+ object = nil
else
- object = record
+ object = record.is_a?(Array) ? record.last : record
object_name = options[:as] || ActiveModel::Naming.param_key(object)
- apply_form_for_options!([object], options)
+ apply_form_for_options!(record, options)
end
- options[:html] ||= {}
options[:html][:remote] = options.delete(:remote)
-
builder = options[:parent_builder] = instantiate_builder(object_name, object, options, &proc)
fields_for = fields_for(object_name, object, options, &proc)
default_options = builder.multipart? ? { :multipart => true } : {}
- output = form_tag(options.delete(:url) || {}, default_options.merge!(options.delete(:html) || {}))
+ output = form_tag(options.delete(:url) || {}, default_options.merge!(options.delete(:html)))
output << fields_for
output.safe_concat('</form>')
end
@@ -329,23 +322,17 @@ module ActionView
object = object_or_array.is_a?(Array) ? object_or_array.last : object_or_array
object = convert_to_model(object)
- html_options =
- if object.respond_to?(:persisted?) && object.persisted?
- { :class => options[:as] ? "#{options[:as]}_edit" : dom_class(object, :edit),
- :id => options[:as] ? "#{options[:as]}_edit" : dom_id(object, :edit),
- :method => :put }
- else
- { :class => options[:as] ? "#{options[:as]}_new" : dom_class(object, :new),
- :id => options[:as] ? "#{options[:as]}_new" : dom_id(object),
- :method => :post }
- end
+ as = options[:as]
+ action, method = object.respond_to?(:persisted?) && object.persisted? ? [:edit, :put] : [:new, :post]
+ options[:html].reverse_merge!(
+ :class => as ? "#{as}_#{action}" : dom_class(object, action),
+ :id => as ? "#{as}_#{action}" : dom_id(object, action),
+ :method => method
+ )
- options[:html] ||= {}
- options[:html].reverse_merge!(html_options)
- options[:url] ||= options[:format] ?
- polymorphic_path(object_or_array, :format => options.delete(:format)) :
- polymorphic_path(object_or_array)
+ options[:url] ||= polymorphic_path(object_or_array, :format => options.delete(:format))
end
+ private :apply_form_for_options!
# Creates a scope around a specific model object like form_for, but
# doesn't create the form tags themselves. This makes fields_for suitable
@@ -863,7 +850,7 @@ module ActionView
extend ActiveSupport::Concern
include Helpers::CaptureHelper, Context, Helpers::TagHelper, Helpers::FormTagHelper
- attr_reader :method_name, :object_name
+ attr_reader :object, :method_name, :object_name
DEFAULT_FIELD_OPTIONS = { "size" => 30 }
DEFAULT_RADIO_OPTIONS = { }
@@ -872,14 +859,9 @@ module ActionView
def initialize(object_name, method_name, template_object, object = nil)
@object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup
@template_object = template_object
- @object = object
- if @object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\]$/,"]")
- if (object ||= @template_object.instance_variable_get("@#{Regexp.last_match.pre_match}")) && object.respond_to?(:to_param)
- @auto_index = object.to_param
- else
- raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}"
- end
- end
+ @object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\]$/,"]")
+ @object = retrieve_object(object)
+ @auto_index = retrieve_autoindex(Regexp.last_match.pre_match) if Regexp.last_match
end
def to_label_tag(text = nil, options = {}, &block)
@@ -1003,14 +985,26 @@ module ActionView
content_tag(tag_name, value(object), options)
end
- def object
- @object || @template_object.instance_variable_get("@#{@object_name}")
+ def retrieve_object(object)
+ if object
+ object
+ elsif @template_object.instance_variable_defined?("@#{@object_name}")
+ @template_object.instance_variable_get("@#{@object_name}")
+ end
rescue NameError
- # As @object_name may contain the nested syntax (item[subobject]) we
- # need to fallback to nil.
+ # As @object_name may contain the nested syntax (item[subobject]) we need to fallback to nil.
nil
end
+ def retrieve_autoindex(pre_match)
+ object = self.object || @template_object.instance_variable_get("@#{pre_match}")
+ if object && object.respond_to?(:to_param)
+ object.to_param
+ else
+ raise ArgumentError, "object[] naming but object param and @object var don't exist or don't respond to to_param: #{object.inspect}"
+ end
+ end
+
def value(object)
self.class.value(object, @method_name)
end
@@ -1183,17 +1177,14 @@ module ActionView
if nested_attributes_association?(record_or_name_or_array)
return fields_for_with_nested_attributes(record_or_name_or_array, args, block)
else
- name = "#{object_name}#{index}[#{record_or_name_or_array}]"
+ name = record_or_name_or_array
end
- when Array
- object = record_or_name_or_array.last
- name = "#{object_name}#{index}[#{ActiveModel::Naming.param_key(object)}]"
- args.unshift(object)
else
- object = record_or_name_or_array
- name = "#{object_name}#{index}[#{ActiveModel::Naming.param_key(object)}]"
+ object = record_or_name_or_array.is_a?(Array) ? record_or_name_or_array.last : record_or_name_or_array
+ name = ActiveModel::Naming.param_key(object)
args.unshift(object)
end
+ name = "#{object_name}#{index}[#{name}]"
@template.fields_for(name, *args, &block)
end
@@ -1253,7 +1244,7 @@ module ActionView
end
def emitted_hidden_id?
- @emitted_hidden_id
+ @emitted_hidden_id ||= nil
end
private
@@ -1262,7 +1253,7 @@ module ActionView
end
def submit_default_value
- object = @object.respond_to?(:to_model) ? @object.to_model : @object
+ object = convert_to_model(@object)
key = object ? (object.persisted? ? :update : :create) : :submit
model = if object.class.respond_to?(:model_name)
@@ -1287,7 +1278,7 @@ module ActionView
name = "#{object_name}[#{association_name}_attributes]"
options = args.extract_options!
association = args.shift
- association = association.to_model if association.respond_to?(:to_model)
+ association = convert_to_model(association)
if association.respond_to?(:persisted?)
association = [association] if @object.send(association_name).is_a?(Array)
@@ -1308,7 +1299,7 @@ module ActionView
end
def fields_for_nested_model(name, object, options, block)
- object = object.to_model if object.respond_to?(:to_model)
+ object = convert_to_model(object)
if object.persisted?
@template.fields_for(name, object, options) do |builder|
@@ -1324,6 +1315,10 @@ module ActionView
@nested_child_index[name] ||= -1
@nested_child_index[name] += 1
end
+
+ def convert_to_model(object)
+ object.respond_to?(:to_model) ? object.to_model : object
+ end
end
end
diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb
index 43cbba8a0a..83434a9340 100644
--- a/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -395,12 +395,12 @@ module ActionView
# <b>Note:</b> Only the <tt><optgroup></tt> and <tt><option></tt> tags are returned, so you still have to
# wrap the output in an appropriate <tt><select></tt> tag.
def option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil)
- collection.inject("") do |options_for_select, group|
+ collection.map do |group|
group_label_string = eval("group.#{group_label_method}")
- options_for_select += "<optgroup label=\"#{html_escape(group_label_string)}\">"
- options_for_select += options_from_collection_for_select(eval("group.#{group_method}"), option_key_method, option_value_method, selected_key)
- options_for_select += '</optgroup>'
- end.html_safe
+ "<optgroup label=\"#{html_escape(group_label_string)}\">" +
+ options_from_collection_for_select(eval("group.#{group_method}"), option_key_method, option_value_method, selected_key) +
+ '</optgroup>'
+ end.join.html_safe
end
# Returns a string of <tt><option></tt> tags, like <tt>options_for_select</tt>, but
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index 43ffadc004..298db46177 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -93,10 +93,6 @@ module ActionView
# # => <select disabled="disabled" id="destination" name="destination"><option>NYC</option>
# # <option>Paris</option><option>Rome</option></select>
def select_tag(name, option_tags = nil, options = {})
- if Array === option_tags
- ActiveSupport::Deprecation.warn 'Passing an array of option_tags to select_tag implicitly joins them without marking them as HTML-safe. Pass option_tags.join.html_safe instead.', caller
- end
-
html_name = (options[:multiple] == true && !name.to_s.ends_with?("[]")) ? "#{name}[]" : name
if blank = options.delete(:include_blank)
if blank.kind_of?(String)
diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb
index 46af3012d9..3bc5afc2c4 100644
--- a/actionpack/lib/action_view/helpers/text_helper.rb
+++ b/actionpack/lib/action_view/helpers/text_helper.rb
@@ -263,7 +263,7 @@ module ActionView
#
# post_body = "Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com."
# auto_link(post_body, :html => { :target => '_blank' }) do |text|
- # truncate(text, 15)
+ # truncate(text, :length => 15)
# end
# # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\" target=\"_blank\">http://www.m...</a>.
# Please e-mail me at <a href=\"mailto:me@email.com\">me@email.com</a>."
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index f8147840ed..1c3ca78d28 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -95,7 +95,7 @@ module ActionView
# # => javascript:history.back()
def url_for(options = {})
options ||= {}
- url = case options
+ case options
when String
options
when Hash
@@ -106,8 +106,6 @@ module ActionView
else
polymorphic_path(options)
end
-
- url
end
# Creates a link tag of the given +name+ using a URL created by the set
@@ -586,20 +584,24 @@ module ActionView
private
def convert_options_to_data_attributes(options, html_options)
- html_options = {} if html_options.nil?
- html_options = html_options.stringify_keys
+ if html_options.nil?
+ link_to_remote_options?(options) ? {'data-remote' => 'true'} : {}
+ else
+ html_options = html_options.stringify_keys
+ html_options['data-remote'] = 'true' if link_to_remote_options?(options) || link_to_remote_options?(html_options)
- if (options.is_a?(Hash) && options.key?('remote') && options.delete('remote')) || (html_options.is_a?(Hash) && html_options.key?('remote') && html_options.delete('remote'))
- html_options['data-remote'] = 'true'
- end
+ confirm = html_options.delete('confirm')
+ method = html_options.delete('method')
- confirm = html_options.delete("confirm")
- method, href = html_options.delete("method"), html_options['href']
+ add_confirm_to_attributes!(html_options, confirm) if confirm
+ add_method_to_attributes!(html_options, method) if method
- add_confirm_to_attributes!(html_options, confirm) if confirm
- add_method_to_attributes!(html_options, method) if method
+ html_options
+ end
+ end
- html_options
+ def link_to_remote_options?(options)
+ options.is_a?(Hash) && options.key?('remote') && options.delete('remote')
end
def add_confirm_to_attributes!(html_options, confirm)
diff --git a/actionpack/lib/action_view/template/error.rb b/actionpack/lib/action_view/template/error.rb
index b1839b65e5..423e1e0bf5 100644
--- a/actionpack/lib/action_view/template/error.rb
+++ b/actionpack/lib/action_view/template/error.rb
@@ -52,6 +52,7 @@ module ActionView
def initialize(template, assigns, original_exception)
@template, @assigns, @original_exception = template, assigns.dup, original_exception
+ @sub_templates = nil
@backtrace = original_exception.backtrace
end
diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb
index c9e20ca14e..a261e08dbc 100644
--- a/actionpack/lib/action_view/template/resolver.rb
+++ b/actionpack/lib/action_view/template/resolver.rb
@@ -6,6 +6,7 @@ module ActionView
# = Action View Resolver
class Resolver
def initialize
+ @path = nil
@cached = Hash.new { |h1,k1| h1[k1] =
Hash.new { |h2,k2| h2[k2] = Hash.new { |h3, k3| h3[k3] = {} } } }
end
diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb
index ff35fb7df4..915c2f90d7 100644
--- a/actionpack/lib/action_view/test_case.rb
+++ b/actionpack/lib/action_view/test_case.rb
@@ -20,12 +20,12 @@ module ActionView
end
def initialize
+ super
self.class.controller_path = ""
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@request.env.delete('PATH_INFO')
-
@params = {}
end
end
@@ -127,6 +127,7 @@ module ActionView
def say_no_to_protect_against_forgery!
_helpers.module_eval do
+ remove_method :protect_against_forgery? if method_defined?(:protect_against_forgery?)
def protect_against_forgery?
false
end
@@ -136,8 +137,10 @@ module ActionView
def make_test_case_available_to_view!
test_case_instance = self
_helpers.module_eval do
- define_method(:_test_case) { test_case_instance }
- private :_test_case
+ unless private_method_defined?(:_test_case)
+ define_method(:_test_case) { test_case_instance }
+ private :_test_case
+ end
end
end
@@ -153,15 +156,15 @@ module ActionView
# The instance of ActionView::Base that is used by +render+.
def view
@view ||= begin
- view = ActionView::Base.new(ActionController::Base.view_paths, {}, @controller)
- view.singleton_class.send :include, _helpers
- view.singleton_class.send :include, @controller._routes.url_helpers
- view.singleton_class.send :delegate, :alert, :notice, :to => "request.flash"
- view.extend(Locals)
- view.locals = self.locals
- view.output_buffer = self.output_buffer
- view
- end
+ view = ActionView::Base.new(ActionController::Base.view_paths, {}, @controller)
+ view.singleton_class.send :include, _helpers
+ view.singleton_class.send :include, @controller._routes.url_helpers
+ view.singleton_class.send :delegate, :alert, :notice, :to => "request.flash"
+ view.extend(Locals)
+ view.locals = self.locals
+ view.output_buffer = self.output_buffer
+ view
+ end
end
alias_method :_view, :view
@@ -198,7 +201,7 @@ module ActionView
def method_missing(selector, *args)
if @controller.respond_to?(:_routes) &&
- @controller._routes.named_routes.helpers.include?(selector)
+ @controller._routes.named_routes.helpers.include?(selector)
@controller.__send__(selector, *args)
else
super
diff --git a/actionpack/lib/action_view/testing/resolvers.rb b/actionpack/lib/action_view/testing/resolvers.rb
index 97de2471cf..b2b62528a9 100644
--- a/actionpack/lib/action_view/testing/resolvers.rb
+++ b/actionpack/lib/action_view/testing/resolvers.rb
@@ -22,10 +22,10 @@ module ActionView #:nodoc:
end
templates = []
- @hash.select { |k,v| k =~ /^#{query}$/ }.each do |path, source|
- handler, format = extract_handler_and_format(path, formats)
- templates << Template.new(source, path, handler,
- :virtual_path => path, :format => format)
+ @hash.select { |k,v| k =~ /^#{query}$/ }.each do |_path, source|
+ handler, format = extract_handler_and_format(_path, formats)
+ templates << Template.new(source, _path, handler,
+ :virtual_path => _path, :format => format)
end
templates.sort_by {|t| -t.identifier.match(/^#{query}$/).captures.reject(&:blank?).size }