diff options
Diffstat (limited to 'actionpack/lib')
19 files changed, 225 insertions, 114 deletions
diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb index 93568da9ef..834d44f045 100644 --- a/actionpack/lib/action_controller/metal/mime_responds.rb +++ b/actionpack/lib/action_controller/metal/mime_responds.rb @@ -420,7 +420,7 @@ module ActionController #:nodoc: end def response - @responses[format] || @responses[Mime::ALL] + @responses.fetch(format, @responses[Mime::ALL]) end def negotiate_format(request) diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb index 17379cf7ac..d275a854fd 100644 --- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb +++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb @@ -50,6 +50,10 @@ module ActionController #:nodoc: config_accessor :request_forgery_protection_token self.request_forgery_protection_token ||= :authenticity_token + # Holds the class which implements the request forgery protection. + config_accessor :forgery_protection_strategy + self.forgery_protection_strategy = nil + # Controls whether request forgery protection is turned on or not. Turned off by default only in test mode. config_accessor :allow_forgery_protection self.allow_forgery_protection = true if allow_forgery_protection.nil? @@ -82,14 +86,14 @@ module ActionController #:nodoc: # * <tt>:reset_session</tt> - Resets the session. # * <tt>:null_session</tt> - Provides an empty session during request but doesn't reset it completely. Used as default if <tt>:with</tt> option is not specified. def protect_from_forgery(options = {}) - include protection_method_module(options[:with] || :null_session) + self.forgery_protection_strategy = protection_method_class(options[:with] || :null_session) self.request_forgery_protection_token ||= :authenticity_token prepend_before_action :verify_authenticity_token, options end private - def protection_method_module(name) + def protection_method_class(name) ActionController::RequestForgeryProtection::ProtectionMethods.const_get(name.to_s.classify) rescue NameError raise ArgumentError, 'Invalid request forgery protection method, use :null_session, :exception, or :reset_session' @@ -97,17 +101,22 @@ module ActionController #:nodoc: end module ProtectionMethods - module NullSession - protected + class NullSession + def initialize(controller) + @controller = controller + end # This is the method that defines the application behavior when a request is found to be unverified. def handle_unverified_request + request = @controller.request request.session = NullSessionHash.new(request.env) request.env['action_dispatch.request.flash_hash'] = nil request.env['rack.session.options'] = { skip: true } request.env['action_dispatch.cookies'] = NullCookieJar.build(request) end + protected + class NullSessionHash < Rack::Session::Abstract::SessionHash #:nodoc: def initialize(env) super(nil, env) @@ -135,16 +144,20 @@ module ActionController #:nodoc: end end - module ResetSession - protected + class ResetSession + def initialize(controller) + @controller = controller + end def handle_unverified_request - reset_session + @controller.reset_session end end - module Exception - protected + class Exception + def initialize(controller) + @controller = controller + end def handle_unverified_request raise ActionController::InvalidAuthenticityToken @@ -153,6 +166,10 @@ module ActionController #:nodoc: end protected + def handle_unverified_request + forgery_protection_strategy.new(self).handle_unverified_request + end + # The actual before_action that is used. Modify this to change how you handle unverified requests. def verify_authenticity_token unless verified_request? diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb index 7e720ca6f5..e4dcd3213f 100644 --- a/actionpack/lib/action_controller/metal/strong_parameters.rb +++ b/actionpack/lib/action_controller/metal/strong_parameters.rb @@ -191,9 +191,9 @@ module ActionController # # +:name+ passes it is a key of +params+ whose associated value is of type # +String+, +Symbol+, +NilClass+, +Numeric+, +TrueClass+, +FalseClass+, - # +Date+, +Time+, +DateTime+, +StringIO+, +IO+, or - # +ActionDispatch::Http::UploadedFile+. Otherwise, the key +:name+ is - # filtered out. + # +Date+, +Time+, +DateTime+, +StringIO+, +IO+, + # +ActionDispatch::Http::UploadedFile+ or +Rack::Test::UploadedFile+. + # Otherwise, the key +:name+ is filtered out. # # You may declare that the parameter should be an array of permitted scalars # by mapping it to an empty array: @@ -374,6 +374,7 @@ module ActionController StringIO, IO, ActionDispatch::Http::UploadedFile, + Rack::Test::UploadedFile, ] def permitted_scalar?(value) diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index ca1ace4537..06e936cdb0 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -1,4 +1,3 @@ -require 'digest/md5' require 'active_support/core_ext/class/attribute_accessors' require 'monitor' diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index e9ef9ee9f2..97ac462411 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -1,3 +1,6 @@ +require 'active_support/core_ext/module/attribute_accessors' +require 'active_support/core_ext/hash/slice' + module ActionDispatch module Http module URL diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index 04cf9d44e1..36a0db6e61 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -410,7 +410,7 @@ module ActionDispatch @encryptor.decrypt_and_verify(encrypted_message) end rescue ActiveSupport::MessageVerifier::InvalidSignature, - ActiveSupport::MessageVerifier::InvalidMessage + ActiveSupport::MessageEncryptor::InvalidMessage nil end diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb index 0898ad82dd..0fa1e9b859 100644 --- a/actionpack/lib/action_dispatch/middleware/params_parser.rb +++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb @@ -13,10 +13,7 @@ module ActionDispatch end end - DEFAULT_PARSERS = { - Mime::XML => :xml_simple, - Mime::JSON => :json - } + DEFAULT_PARSERS = { Mime::JSON => :json } def initialize(app, parsers = {}) @app, @parsers = app, DEFAULT_PARSERS.merge(parsers) @@ -36,19 +33,13 @@ module ActionDispatch return false if request.content_length.zero? - mime_type = content_type_from_legacy_post_data_format_header(env) || - request.content_mime_type - - strategy = @parsers[mime_type] + strategy = @parsers[request.content_mime_type] return false unless strategy case strategy when Proc strategy.call(request.raw_post) - when :xml_simple, :xml_node - data = request.deep_munge(Hash.from_xml(request.body.read) || {}) - data.with_indifferent_access when :json data = ActiveSupport::JSON.decode(request.body) data = {:_json => data} unless data.is_a?(Hash) @@ -56,23 +47,12 @@ module ActionDispatch else false end - rescue Exception => e # YAML, XML or Ruby code block errors + rescue Exception => e # JSON or Ruby code block errors logger(env).debug "Error occurred while parsing request parameters.\nContents:\n\n#{request.raw_post}" raise ParseError.new(e.message, e) end - def content_type_from_legacy_post_data_format_header(env) - if x_post_format = env['HTTP_X_POST_DATA_FORMAT'] - case x_post_format.to_s.downcase - when 'yaml' then return Mime::YAML - when 'xml' then return Mime::XML - end - end - - nil - end - def logger(env) env['action_dispatch.logger'] || ActiveSupport::Logger.new($stderr) end diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb index 4c5cb27feb..93a2b52996 100644 --- a/actionpack/lib/action_dispatch/middleware/remote_ip.rb +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -83,7 +83,7 @@ module ActionDispatch # This constant contains a regular expression that validates every known # form of IP v4 and v6 address, with or without abbreviations, adapted - # from {this gist}[https://gist.github.com/1289635]. + # from {this gist}[https://gist.github.com/gazay/1289635]. VALID_IP = %r{ (^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})){3}$) | # ip v4 (^( 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 ab24118f3e..550f4dbd0d 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 @@ -1,6 +1,6 @@ <% unless @exception.blamed_files.blank? %> <% if (hide = @exception.blamed_files.length > 8) %> - <a href="#" onclick="toggleTrace()">Toggle blamed files</a> + <a href="#" onclick="return toggleTrace()">Toggle blamed files</a> <% end %> <pre id="blame_trace" <%='style="display:none"' if hide %>><code><%= @exception.describe_blame %></code></pre> <% end %> @@ -21,12 +21,12 @@ <p><b>Parameters</b>:</p> <pre><%= request_dump %></pre> <div class="details"> - <div class="summary"><a href="#" onclick="toggleSessionDump()">Toggle session dump</a></div> + <div class="summary"><a href="#" onclick="return toggleSessionDump()">Toggle session dump</a></div> <div id="session_dump" style="display:none"><pre><%= debug_hash @request.session %></pre></div> </div> <div class="details"> - <div class="summary"><a href="#" onclick="toggleEnvDump()">Toggle env dump</a></div> + <div class="summary"><a href="#" onclick="return toggleEnvDump()">Toggle env dump</a></div> <div id="env_dump" style="display:none"><pre><%= debug_hash @request.env.slice(*@request.class::ENV_METHODS) %></pre></div> </div> diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb index 9878c2747e..891c87ac27 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/layout.erb @@ -121,6 +121,7 @@ var toggle = function(id) { var s = document.getElementById(id).style; s.display = s.display == 'none' ? 'block' : 'none'; + return false; } var show = function(id) { document.getElementById(id).style.display = 'block'; @@ -129,13 +130,13 @@ document.getElementById(id).style.display = 'none'; } var toggleTrace = function() { - toggle('blame_trace'); + return toggle('blame_trace'); } var toggleSessionDump = function() { - toggle('session_dump'); + return toggle('session_dump'); } var toggleEnvDump = function() { - toggle('env_dump'); + return toggle('env_dump'); } </script> </head> diff --git a/actionpack/lib/action_dispatch/routing/inspector.rb b/actionpack/lib/action_dispatch/routing/inspector.rb index bc6dd7145c..d251de33df 100644 --- a/actionpack/lib/action_dispatch/routing/inspector.rb +++ b/actionpack/lib/action_dispatch/routing/inspector.rb @@ -1,4 +1,5 @@ require 'delegate' +require 'active_support/core_ext/string/strip' module ActionDispatch module Routing @@ -90,6 +91,13 @@ module ActionDispatch routes_to_display = filter_routes(filter) routes = collect_routes(routes_to_display) + + if routes.none? + formatter.no_routes + return formatter.result + end + + formatter.header routes formatter.section routes @engines.each do |name, engine_routes| @@ -155,16 +163,40 @@ module ActionDispatch @buffer << draw_section(routes) end + def header(routes) + @buffer << draw_header(routes) + end + + def no_routes + @buffer << <<-MESSAGE.strip_heredoc + You don't have any routes defined! + + Please add some routes in config/routes.rb. + + For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html. + MESSAGE + end + private def draw_section(routes) - name_width = routes.map { |r| r[:name].length }.max - verb_width = routes.map { |r| r[:verb].length }.max - path_width = routes.map { |r| r[:path].length }.max + name_width, verb_width, path_width = widths(routes) routes.map do |r| "#{r[:name].rjust(name_width)} #{r[:verb].ljust(verb_width)} #{r[:path].ljust(path_width)} #{r[:reqs]}" end end + + def draw_header(routes) + name_width, verb_width, path_width = widths(routes) + + "#{"Prefix".rjust(name_width)} #{"Verb".ljust(verb_width)} #{"URI Pattern".ljust(path_width)} Controller#Action" + end + + def widths(routes) + [routes.map { |r| r[:name].length }.max, + routes.map { |r| r[:verb].length }.max, + routes.map { |r| r[:path].length }.max] + end end class HtmlTableFormatter @@ -181,6 +213,23 @@ module ActionDispatch @buffer << @view.render(partial: "routes/route", collection: routes) end + # the header is part of the HTML page, so we don't construct it here. + def header(routes) + end + + def no_routes + @buffer << <<-MESSAGE.strip_heredoc + <p>You don't have any routes defined!</p> + <ul> + <li>Please add some routes in <tt>config/routes.rb</tt>.</li> + <li> + For more information about routes, please see the Rails guide + <a href="http://guides.rubyonrails.org/routing.html">Rails Routing from the Outside In</a>. + </li> + </ul> + MESSAGE + end + def result @view.raw @view.render(layout: "routes/table") { @view.raw @buffer.join("\n") diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 0a41ed0fcf..817480c7ae 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -50,7 +50,6 @@ module ActionDispatch class Mapping #:nodoc: IGNORE_OPTIONS = [:to, :as, :via, :on, :constraints, :defaults, :only, :except, :anchor, :shallow, :shallow_path, :shallow_prefix, :format] ANCHOR_CHARACTERS_REGEX = %r{\A(\\A|\^)|(\\Z|\\z|\$)\Z} - SHORTHAND_REGEX = %r{/[\w/]+$} WILDCARD_PATH = %r{\*([^/\)]+)\)?$} attr_reader :scope, :path, :options, :requirements, :conditions, :defaults @@ -111,17 +110,7 @@ module ActionDispatch @options[:controller] ||= /.+?/ end - if using_match_shorthand?(path_without_format, @options) - to_shorthand = @options[:to].blank? - @options[:to] ||= path_without_format.gsub(/\(.*\)/, "")[1..-1].sub(%r{/([^/]*)$}, '#\1') - end - - @options.merge!(default_controller_and_action(to_shorthand)) - end - - # match "account/overview" - def using_match_shorthand?(path, options) - path && (options[:to] || options[:action]).nil? && path =~ SHORTHAND_REGEX + @options.merge!(default_controller_and_action) end def normalize_format! @@ -214,7 +203,7 @@ module ActionDispatch Constraints.new(endpoint, blocks, @set.request_class) end - def default_controller_and_action(to_shorthand=nil) + def default_controller_and_action if to.respond_to?(:call) { } else @@ -227,7 +216,7 @@ module ActionDispatch controller ||= default_controller action ||= default_action - unless controller.is_a?(Regexp) || to_shorthand + unless controller.is_a?(Regexp) controller = [@scope[:module], controller].compact.join("/").presence end @@ -340,7 +329,6 @@ module ActionDispatch # because this means it will be matched first. As this is the most popular route # of most Rails applications, this is beneficial. def root(options = {}) - options = { :to => options } if options.is_a?(String) match '/', { :as => :root, :via => :get }.merge!(options) end @@ -1383,6 +1371,11 @@ module ActionDispatch paths = [path] + rest end + path_without_format = path.to_s.sub(/\(\.:format\)$/, '') + if using_match_shorthand?(path_without_format, options) + options[:to] ||= path_without_format.gsub(%r{^/}, "").sub(%r{/([^/]*)$}, '#\1') + end + options[:anchor] = true unless options.key?(:anchor) if options[:on] && !VALID_ON_OPTIONS.include?(options[:on]) @@ -1393,6 +1386,10 @@ module ActionDispatch self end + def using_match_shorthand?(path, options) + path && (options[:to] || options[:action]).nil? && path =~ %r{/[\w/]+$} + end + def decomposed_match(path, options) # :nodoc: if on = options.delete(:on) send(on) { decomposed_match(path, options) } @@ -1429,7 +1426,15 @@ module ActionDispatch @set.add_route(app, conditions, requirements, defaults, as, anchor) end - def root(options={}) + def root(path, options={}) + if path.is_a?(String) + options[:to] = path + elsif path.is_a?(Hash) and options.empty? + options = path + else + raise ArgumentError, "must be called with a path and/or options" + end + if @scope[:scope_level] == :resources with_scope_level(:root) do scope(parent_resource.path) do diff --git a/actionpack/lib/action_pack/version.rb b/actionpack/lib/action_pack/version.rb index 94cbc8e478..5c87a9cd7c 100644 --- a/actionpack/lib/action_pack/version.rb +++ b/actionpack/lib/action_pack/version.rb @@ -3,7 +3,7 @@ module ActionPack MAJOR = 4 MINOR = 0 TINY = 0 - PRE = "beta" + PRE = "beta1" STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') end diff --git a/actionpack/lib/action_view/dependency_tracker.rb b/actionpack/lib/action_view/dependency_tracker.rb new file mode 100644 index 0000000000..3de5cd150b --- /dev/null +++ b/actionpack/lib/action_view/dependency_tracker.rb @@ -0,0 +1,91 @@ +require 'thread_safe' + +module ActionView + class DependencyTracker + @trackers = ThreadSafe::Cache.new + + def self.find_dependencies(name, template) + tracker = @trackers[template.handler] + + if tracker.present? + tracker.call(name, template) + else + [] + end + end + + def self.register_tracker(extension, tracker) + handler = Template.handler_for_extension(extension) + @trackers[handler] = tracker + end + + def self.remove_tracker(handler) + @trackers.delete(handler) + end + + class ERBTracker + EXPLICIT_DEPENDENCY = /# Template Dependency: (\S+)/ + + # Matches: + # render partial: "comments/comment", collection: commentable.comments + # render "comments/comments" + # render 'comments/comments' + # render('comments/comments') + # + # render(@topic) => render("topics/topic") + # render(topics) => render("topics/topic") + # render(message.topics) => render("topics/topic") + RENDER_DEPENDENCY = / + render\s* # render, followed by optional whitespace + \(? # start an optional parenthesis for the render call + (partial:|:partial\s+=>)?\s* # naming the partial, used with collection -- 1st capture + ([@a-z"'][@a-z_\/\."']+) # the template name itself -- 2nd capture + /x + + def self.call(name, template) + new(name, template).dependencies + end + + def initialize(name, template) + @name, @template = name, template + end + + def dependencies + render_dependencies + explicit_dependencies + end + + private + attr_reader :name, :template + + def source + template.source + end + + def directory + name.split("/")[0..-2].join("/") + end + + def render_dependencies + source.scan(RENDER_DEPENDENCY). + collect(&:second).uniq. + + # render(@topic) => render("topics/topic") + # render(topics) => render("topics/topic") + # render(message.topics) => render("topics/topic") + collect { |name| name.sub(/\A@?([a-z]+\.)*([a-z_]+)\z/) { "#{$2.pluralize}/#{$2.singularize}" } }. + + # render("headline") => render("message/headline") + collect { |name| name.include?("/") ? name : "#{directory}/#{name}" }. + + # replace quotes from string renders + collect { |name| name.gsub(/["']/, "") } + end + + def explicit_dependencies + source.scan(EXPLICIT_DEPENDENCY).flatten.uniq + end + end + + register_tracker :erb, ERBTracker + end +end diff --git a/actionpack/lib/action_view/digestor.rb b/actionpack/lib/action_view/digestor.rb index 4507861dcc..9324a1ac50 100644 --- a/actionpack/lib/action_view/digestor.rb +++ b/actionpack/lib/action_view/digestor.rb @@ -1,25 +1,8 @@ require 'thread_safe' +require 'action_view/dependency_tracker' module ActionView class Digestor - EXPLICIT_DEPENDENCY = /# Template Dependency: (\S+)/ - - # Matches: - # render partial: "comments/comment", collection: commentable.comments - # render "comments/comments" - # render 'comments/comments' - # render('comments/comments') - # - # render(@topic) => render("topics/topic") - # render(topics) => render("topics/topic") - # render(message.topics) => render("topics/topic") - RENDER_DEPENDENCY = / - render\s* # render, followed by optional whitespace - \(? # start an optional parenthesis for the render call - (partial:|:partial\s+=>)?\s* # naming the partial, used with collection -- 1st capture - ([@a-z"'][@a-z_\/\."']+) # the template name itself -- 2nd capture - /x - cattr_reader(:cache) @@cache = ThreadSafe::Cache.new @@ -47,7 +30,7 @@ module ActionView end def dependencies - render_dependencies + explicit_dependencies + DependencyTracker.find_dependencies(name, template) rescue ActionView::MissingTemplate [] # File doesn't exist, so no dependencies end @@ -69,16 +52,16 @@ module ActionView name.gsub(%r|/_|, "/") end - def directory - name.split("/")[0..-2].join("/") - end - def partial? false end + def template + @template ||= finder.find(logical_name, [], partial?, formats: [ format ]) + end + def source - @source ||= finder.find(logical_name, [], partial?, formats: [ format ]).source + template.source end def dependency_digest @@ -89,26 +72,6 @@ module ActionView (template_digests + injected_dependencies).join("-") end - def render_dependencies - source.scan(RENDER_DEPENDENCY). - collect(&:second).uniq. - - # render(@topic) => render("topics/topic") - # render(topics) => render("topics/topic") - # render(message.topics) => render("topics/topic") - collect { |name| name.sub(/\A@?([a-z]+\.)*([a-z_]+)\z/) { "#{$2.pluralize}/#{$2.singularize}" } }. - - # render("headline") => render("message/headline") - collect { |name| name.include?("/") ? name : "#{directory}/#{name}" }. - - # replace quotes from string renders - collect { |name| name.gsub(/["']/, "") } - end - - def explicit_dependencies - source.scan(EXPLICIT_DEPENDENCY).flatten.uniq - end - def injected_dependencies Array.wrap(options[:dependencies]) end diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index a989966613..d3953c26b7 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -642,6 +642,8 @@ module ActionView # <time datetime="2010-11-03">Yesterday</time> # time_tag Date.today, pubdate: true # => # <time datetime="2010-11-04" pubdate="pubdate">November 04, 2010</time> + # time_tag Date.today, datetime: Date.today.strftime('%G-W%V') # => + # <time datetime="2010-W44">November 04, 2010</time> # # <%= time_tag Time.now do %> # <span>Right now</span> @@ -651,7 +653,7 @@ module ActionView options = args.extract_options! format = options.delete(:format) || :long content = args.first || I18n.l(date_or_time, :format => format) - datetime = date_or_time.acts_like?(:time) ? date_or_time.xmlschema : date_or_time.rfc3339 + datetime = date_or_time.acts_like?(:time) ? date_or_time.xmlschema : date_or_time.iso8601 content_tag(:time, content, options.reverse_merge(:datetime => datetime), &block) end diff --git a/actionpack/lib/action_view/helpers/debug_helper.rb b/actionpack/lib/action_view/helpers/debug_helper.rb index 34fc23ac1a..c29c1b1eea 100644 --- a/actionpack/lib/action_view/helpers/debug_helper.rb +++ b/actionpack/lib/action_view/helpers/debug_helper.rb @@ -32,7 +32,7 @@ module ActionView content_tag(:pre, object, :class => "debug_dump") rescue Exception # errors from Marshal or YAML # Object couldn't be dumped, perhaps because of singleton methods -- this is the fallback - content_tag(:code, object.to_yaml, :class => "debug_dump") + content_tag(:code, object.inspect, :class => "debug_dump") 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 8b3a37a853..377819a80c 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -565,14 +565,14 @@ module ActionView if priority_zones if priority_zones.is_a?(Regexp) - priority_zones = zones.select { |z| z =~ priority_zones } + priority_zones = zones.grep(priority_zones) end zone_options.safe_concat options_for_select(convert_zones[priority_zones], selected) zone_options.safe_concat content_tag(:option, '-------------', :value => '', :disabled => 'disabled') zone_options.safe_concat "\n" - zones.reject! { |z| priority_zones.include?(z) } + zones = zones - priority_zones end zone_options.safe_concat options_for_select(convert_zones[zones], selected) diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb index 86d9f94067..1adc8225f1 100644 --- a/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb @@ -33,7 +33,7 @@ module ActionView # (by passing <tt>false</tt>). Remote forms may omit the embedded authenticity token # by setting <tt>config.action_view.embed_authenticity_token_in_remote_forms = false</tt>. # This is helpful when you're fragment-caching the form. Remote forms get the - # authenticity from the <tt>meta</tt> tag, so embedding is unnecessary unless you + # authenticity token from the <tt>meta</tt> tag, so embedding is unnecessary unless you # support browsers without JavaScript. # * A list of parameters to feed to the URL the form will be posted to. # * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the |