diff options
Diffstat (limited to 'actionview/lib/action_view')
18 files changed, 129 insertions, 96 deletions
diff --git a/actionview/lib/action_view/base.rb b/actionview/lib/action_view/base.rb index 43124bb904..72ca6f7ec6 100644 --- a/actionview/lib/action_view/base.rb +++ b/actionview/lib/action_view/base.rb @@ -161,6 +161,10 @@ module ActionView #:nodoc: cattr_accessor :raise_on_missing_translations @@raise_on_missing_translations = false + # Specify whether submit_tag should automatically disable on click + cattr_accessor :automatically_disable_submit_tag + @@automatically_disable_submit_tag = true + class_attribute :_routes class_attribute :logger diff --git a/actionview/lib/action_view/helpers/asset_tag_helper.rb b/actionview/lib/action_view/helpers/asset_tag_helper.rb index 3041ad3ef7..e506c782d6 100644 --- a/actionview/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionview/lib/action_view/helpers/asset_tag_helper.rb @@ -60,7 +60,7 @@ module ActionView tag_options = { "src" => path_to_javascript(source, path_options) }.merge!(options) - content_tag(:script, "", tag_options) + content_tag("script".freeze, "", tag_options) }.join("\n").html_safe end diff --git a/actionview/lib/action_view/helpers/asset_url_helper.rb b/actionview/lib/action_view/helpers/asset_url_helper.rb index 3beb7fefb1..717b326740 100644 --- a/actionview/lib/action_view/helpers/asset_url_helper.rb +++ b/actionview/lib/action_view/helpers/asset_url_helper.rb @@ -31,26 +31,33 @@ module ActionView # stylesheet_link_tag("application") # # => <link href="http://assets.example.com/assets/application.css" media="screen" rel="stylesheet" /> # - # Browsers typically open at most two simultaneous connections to a single - # host, which means your assets often have to wait for other assets to finish - # downloading. You can alleviate this by using a <tt>%d</tt> wildcard in the - # +asset_host+. For example, "assets%d.example.com". If that wildcard is - # present Rails distributes asset requests among the corresponding four hosts - # "assets0.example.com", ..., "assets3.example.com". With this trick browsers - # will open eight simultaneous connections rather than two. + # Browsers open a limited number of simultaneous connections to a single + # host. The exact number varies by browser and version. This limit may cause + # some asset downloads to wait for previous assets to finish before they can + # begin. You can use the <tt>%d</tt> wildcard in the +asset_host+ to + # distribute the requests over four hosts. For example, + # <tt>assets%d.example.com<tt> will spread the asset requests over + # "assets0.example.com", ..., "assets3.example.com". # # image_tag("rails.png") # # => <img alt="Rails" src="http://assets0.example.com/assets/rails.png" /> # stylesheet_link_tag("application") # # => <link href="http://assets2.example.com/assets/application.css" media="screen" rel="stylesheet" /> # - # To do this, you can either setup four actual hosts, or you can use wildcard - # DNS to CNAME the wildcard to a single asset host. You can read more about - # setting up your DNS CNAME records from your ISP. + # This may improve the asset loading performance of your application. + # It is also possible the combination of additional connection overhead + # (DNS, SSL) and the overall browser connection limits may result in this + # solution being slower. You should be sure to measure your actual + # performance across targeted browsers both before and after this change. + # + # To implement the corresponding hosts you can either setup four actual + # hosts or use wildcard DNS to CNAME the wildcard to a single asset host. + # You can read more about setting up your DNS CNAME records from your ISP. # # Note: This is purely a browser performance optimization and is not meant # for server load balancing. See http://www.die.net/musings/page_load_time/ - # for background. + # for background and http://www.browserscope.org/?category=network for + # connection limit data. # # Alternatively, you can exert more control over the asset host by setting # +asset_host+ to a proc like this: diff --git a/actionview/lib/action_view/helpers/date_helper.rb b/actionview/lib/action_view/helpers/date_helper.rb index fbd7261477..312e41ee48 100644 --- a/actionview/lib/action_view/helpers/date_helper.rb +++ b/actionview/lib/action_view/helpers/date_helper.rb @@ -228,6 +228,7 @@ module ActionView # or the given prompt string. # * <tt>:with_css_classes</tt> - Set to true if you want assign different styles for 'select' tags. This option # automatically set classes 'year', 'month', 'day', 'hour', 'minute' and 'second' for your 'select' tags. + # * <tt>:use_hidden</tt> - Set to true if you only want to generate hidden input tags. # # If anything is passed in the +html_options+ hash it will be applied to every select tag in the set. # @@ -681,7 +682,7 @@ module ActionView content = args.first || I18n.l(date_or_time, :format => format) 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) + content_tag("time".freeze, content, options.reverse_merge(:datetime => datetime), &block) end end @@ -809,7 +810,7 @@ module ActionView 1.upto(12) do |month_number| options = { :value => month_number } options[:selected] = "selected" if month == month_number - month_options << content_tag(:option, month_name(month_number), options) + "\n" + month_options << content_tag("option".freeze, month_name(month_number), options) + "\n" end build_select(:month, month_options.join) end @@ -971,7 +972,7 @@ module ActionView tag_options[:selected] = "selected" if selected == i text = options[:use_two_digit_numbers] ? sprintf("%02d", i) : value text = options[:ampm] ? AMPM_TRANSLATION[i] : text - select_options << content_tag(:option, text, tag_options) + select_options << content_tag("option".freeze, text, tag_options) end (select_options.join("\n") + "\n").html_safe @@ -991,11 +992,11 @@ module ActionView select_options[:class] = [select_options[:class], type].compact.join(' ') if @options[:with_css_classes] select_html = "\n" - select_html << content_tag(:option, '', :value => '') + "\n" if @options[:include_blank] + select_html << content_tag("option".freeze, '', :value => '') + "\n" if @options[:include_blank] select_html << prompt_option_tag(type, @options[:prompt]) + "\n" if @options[:prompt] select_html << select_options_as_html - (content_tag(:select, select_html.html_safe, select_options) + "\n").html_safe + (content_tag("select".freeze, select_html.html_safe, select_options) + "\n").html_safe end # Builds a prompt option tag with supplied options or from default options. @@ -1012,7 +1013,7 @@ module ActionView I18n.translate(:"datetime.prompts.#{type}", :locale => @options[:locale]) end - prompt ? content_tag(:option, prompt, :value => '') : '' + prompt ? content_tag("option".freeze, prompt, :value => '') : '' end # Builds hidden input tag for date part and value. diff --git a/actionview/lib/action_view/helpers/form_options_helper.rb b/actionview/lib/action_view/helpers/form_options_helper.rb index 8e729b3c39..728e633bbf 100644 --- a/actionview/lib/action_view/helpers/form_options_helper.rb +++ b/actionview/lib/action_view/helpers/form_options_helper.rb @@ -456,7 +456,7 @@ module ActionView option_tags = options_from_collection_for_select( group.send(group_method), option_key_method, option_value_method, selected_key) - content_tag(:optgroup, option_tags, label: group.send(group_label_method)) + content_tag("optgroup".freeze, option_tags, label: group.send(group_label_method)) end.join.html_safe end @@ -528,7 +528,7 @@ module ActionView body = "".html_safe if prompt - body.safe_concat content_tag(:option, prompt_text(prompt), value: "") + body.safe_concat content_tag("option".freeze, prompt_text(prompt), value: "") end grouped_options.each do |container| @@ -541,7 +541,7 @@ module ActionView end html_attributes = { label: label }.merge!(html_attributes) - body.safe_concat content_tag(:optgroup, options_for_select(container, selected_key), html_attributes) + body.safe_concat content_tag("optgroup".freeze, options_for_select(container, selected_key), html_attributes) end body @@ -577,7 +577,7 @@ module ActionView end zone_options.safe_concat options_for_select(convert_zones[priority_zones], selected) - zone_options.safe_concat content_tag(:option, '-------------', value: '', disabled: true) + zone_options.safe_concat content_tag("option".freeze, '-------------', value: '', disabled: true) zone_options.safe_concat "\n" zones = zones - priority_zones diff --git a/actionview/lib/action_view/helpers/form_tag_helper.rb b/actionview/lib/action_view/helpers/form_tag_helper.rb index 896020bc15..af684e05c6 100644 --- a/actionview/lib/action_view/helpers/form_tag_helper.rb +++ b/actionview/lib/action_view/helpers/form_tag_helper.rb @@ -140,15 +140,15 @@ module ActionView end if include_blank - option_tags = content_tag(:option, include_blank, value: '').safe_concat(option_tags) + option_tags = content_tag("option".freeze, include_blank, value: '').safe_concat(option_tags) end end if prompt = options.delete(:prompt) - option_tags = content_tag(:option, prompt, value: '').safe_concat(option_tags) + option_tags = content_tag("option".freeze, prompt, value: '').safe_concat(option_tags) end - content_tag :select, option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys) + content_tag "select".freeze, option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys) end # Creates a standard text field; use these text fields to input smaller chunks of text like a username @@ -414,34 +414,48 @@ module ActionView # the form is processed normally, otherwise no action is taken. # * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a # disabled version of the submit button when the form is submitted. This feature is - # provided by the unobtrusive JavaScript driver. + # provided by the unobtrusive JavaScript driver. To disable this feature for a single submit tag + # pass <tt>:data => { disable_with: false }</tt> Defaults to value attribute. # # ==== Examples # submit_tag - # # => <input name="commit" type="submit" value="Save changes" /> + # # => <input name="commit" data-disable-with="Save changes" type="submit" value="Save changes" /> # # submit_tag "Edit this article" - # # => <input name="commit" type="submit" value="Edit this article" /> + # # => <input name="commit" data-disable-with="Edit this article" type="submit" value="Edit this article" /> # # submit_tag "Save edits", disabled: true - # # => <input disabled="disabled" name="commit" type="submit" value="Save edits" /> + # # => <input disabled="disabled" name="commit" data-disable-with="Save edits" type="submit" value="Save edits" /> # - # submit_tag "Complete sale", data: { disable_with: "Please wait..." } - # # => <input name="commit" data-disable-with="Please wait..." type="submit" value="Complete sale" /> + # submit_tag "Complete sale", data: { disable_with: "Submitting..." } + # # => <input name="commit" data-disable-with="Submitting..." type="submit" value="Complete sale" /> # # submit_tag nil, class: "form_submit" # # => <input class="form_submit" name="commit" type="submit" /> # # submit_tag "Edit", class: "edit_button" - # # => <input class="edit_button" name="commit" type="submit" value="Edit" /> + # # => <input class="edit_button" data-disable-with="Edit" name="commit" type="submit" value="Edit" /> # # submit_tag "Save", data: { confirm: "Are you sure?" } - # # => <input name='commit' type='submit' value='Save' data-confirm="Are you sure?" /> + # # => <input name='commit' type='submit' value='Save' data-disable-with="Save" data-confirm="Are you sure?" /> # def submit_tag(value = "Save changes", options = {}) options = options.stringify_keys + tag_options = { "type" => "submit", "name" => "commit", "value" => value }.update(options) + + if ActionView::Base.automatically_disable_submit_tag + unless tag_options["data-disable-with"] == false || (tag_options["data"] && tag_options["data"][:disable_with] == false) + disable_with_text = tag_options["data-disable-with"] + disable_with_text ||= tag_options["data"][:disable_with] if tag_options["data"] + disable_with_text ||= value.clone + tag_options.deep_merge!("data" => { "disable_with" => disable_with_text }) + else + tag_options.delete("data-disable-with") + tag_options["data"].delete(:disable_with) if tag_options["data"] + end + end - tag :input, { "type" => "submit", "name" => "commit", "value" => value }.update(options) + tag :input, tag_options end # Creates a button element that defines a <tt>submit</tt> button, @@ -568,7 +582,7 @@ module ActionView # # => <fieldset class="format"><p><input id="name" name="name" type="text" /></p></fieldset> def field_set_tag(legend = nil, options = nil, &block) output = tag(:fieldset, options, true) - output.safe_concat(content_tag(:legend, legend)) unless legend.blank? + output.safe_concat(content_tag("legend".freeze, legend)) unless legend.blank? output.concat(capture(&block)) if block_given? output.safe_concat("</fieldset>") end diff --git a/actionview/lib/action_view/helpers/javascript_helper.rb b/actionview/lib/action_view/helpers/javascript_helper.rb index e237a32cb7..ed7e882c94 100644 --- a/actionview/lib/action_view/helpers/javascript_helper.rb +++ b/actionview/lib/action_view/helpers/javascript_helper.rb @@ -47,8 +47,8 @@ module ActionView # tag. # # javascript_tag "alert('All is good')", defer: 'defer' - # - # Returns: + # + # Returns: # <script defer="defer"> # //<![CDATA[ # alert('All is good') @@ -70,7 +70,7 @@ module ActionView content_or_options_with_block end - content_tag(:script, javascript_cdata_section(content), html_options) + content_tag("script".freeze, javascript_cdata_section(content), html_options) end def javascript_cdata_section(content) #:nodoc: diff --git a/actionview/lib/action_view/helpers/sanitize_helper.rb b/actionview/lib/action_view/helpers/sanitize_helper.rb index a2e9f37453..191a881de0 100644 --- a/actionview/lib/action_view/helpers/sanitize_helper.rb +++ b/actionview/lib/action_view/helpers/sanitize_helper.rb @@ -120,7 +120,7 @@ module ActionView attr_writer :full_sanitizer, :link_sanitizer, :white_list_sanitizer # Vendors the full, link and white list sanitizers. - # Provided strictly for compabitility and can be removed in Rails 5. + # Provided strictly for compatibility and can be removed in Rails 5. def sanitizer_vendor Rails::Html::Sanitizer end diff --git a/actionview/lib/action_view/helpers/tag_helper.rb b/actionview/lib/action_view/helpers/tag_helper.rb index a87c223a71..2562504896 100644 --- a/actionview/lib/action_view/helpers/tag_helper.rb +++ b/actionview/lib/action_view/helpers/tag_helper.rb @@ -22,9 +22,10 @@ module ActionView TAG_PREFIXES = ['aria', 'data', :aria, :data].to_set - PRE_CONTENT_STRINGS = { - :textarea => "\n" - } + PRE_CONTENT_STRINGS = Hash.new { "".freeze } + PRE_CONTENT_STRINGS[:textarea] = "\n" + PRE_CONTENT_STRINGS["textarea"] = "\n" + # Returns an empty HTML tag of type +name+ which by default is XHTML # compliant. Set +open+ to true to create an open tag compatible @@ -143,24 +144,30 @@ module ActionView def content_tag_string(name, content, options, escape = true) tag_options = tag_options(options, escape) if options content = ERB::Util.unwrapped_html_escape(content) if escape - "<#{name}#{tag_options}>#{PRE_CONTENT_STRINGS[name.to_sym]}#{content}</#{name}>".html_safe + "<#{name}#{tag_options}>#{PRE_CONTENT_STRINGS[name]}#{content}</#{name}>".html_safe end def tag_options(options, escape = true) return if options.blank? - attrs = [] + output = "" + sep = " ".freeze options.each_pair do |key, value| if TAG_PREFIXES.include?(key) && value.is_a?(Hash) value.each_pair do |k, v| - attrs << prefix_tag_option(key, k, v, escape) + output << sep + output << prefix_tag_option(key, k, v, escape) end elsif BOOLEAN_ATTRIBUTES.include?(key) - attrs << boolean_tag_option(key) if value + if value + output << sep + output << boolean_tag_option(key) + end elsif !value.nil? - attrs << tag_option(key, value, escape) + output << sep + output << tag_option(key, value, escape) end end - " #{attrs * ' '}" unless attrs.empty? + output unless output.empty? end def prefix_tag_option(prefix, key, value, escape) @@ -177,7 +184,7 @@ module ActionView def tag_option(key, value, escape) if value.is_a?(Array) - value = escape ? safe_join(value, " ") : value.join(" ") + value = escape ? safe_join(value, " ".freeze) : value.join(" ".freeze) else value = escape ? ERB::Util.unwrapped_html_escape(value) : value end diff --git a/actionview/lib/action_view/helpers/text_helper.rb b/actionview/lib/action_view/helpers/text_helper.rb index 6a3d01667d..432693bc23 100644 --- a/actionview/lib/action_view/helpers/text_helper.rb +++ b/actionview/lib/action_view/helpers/text_helper.rb @@ -250,12 +250,15 @@ module ActionView # # word_wrap('Once upon a time', line_width: 1) # # => Once\nupon\na\ntime - def word_wrap(text, options = {}) - line_width = options.fetch(:line_width, 80) - + # + # You can also specify a custom +break_sequence+ ("\n" by default) + # + # word_wrap('Once upon a time', line_width: 1, break_sequence: "\r\n") + # # => Once\r\nupon\r\na\r\ntime + def word_wrap(text, line_width: 80, break_sequence: "\n") text.split("\n").collect! do |line| - line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip : line - end * "\n" + line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1#{break_sequence}").strip : line + end * break_sequence end # Returns +text+ transformed into HTML using simple formatting rules. diff --git a/actionview/lib/action_view/helpers/url_helper.rb b/actionview/lib/action_view/helpers/url_helper.rb index 7d92651183..d676a0a931 100644 --- a/actionview/lib/action_view/helpers/url_helper.rb +++ b/actionview/lib/action_view/helpers/url_helper.rb @@ -184,9 +184,9 @@ module ActionView html_options = convert_options_to_data_attributes(options, html_options) url = url_for(options) - html_options['href'] ||= url + html_options["href".freeze] ||= url - content_tag(:a, name || url, html_options, &block) + content_tag("a".freeze, name || url, html_options, &block) end # Generates a form containing a single button that submits to the URL created @@ -471,7 +471,7 @@ module ActionView encoded_email_address = ERB::Util.url_encode(email_address).gsub("%40", "@") html_options["href"] = "mailto:#{encoded_email_address}#{extras}" - content_tag(:a, name || email_address, html_options, &block) + content_tag("a".freeze, name || email_address, html_options, &block) end # True if the current request URI was generated by the given +options+. diff --git a/actionview/lib/action_view/layouts.rb b/actionview/lib/action_view/layouts.rb index 9d636c8c9e..cabba967c9 100644 --- a/actionview/lib/action_view/layouts.rb +++ b/actionview/lib/action_view/layouts.rb @@ -277,7 +277,7 @@ module ActionView remove_possible_method(:_layout) prefixes = _implied_layout_name =~ /\blayouts/ ? [] : ["layouts"] - default_behavior = "lookup_context.find_all('#{_implied_layout_name}', #{prefixes.inspect}).first || super" + default_behavior = "lookup_context.find_all('#{_implied_layout_name}', #{prefixes.inspect}, false, [], { formats: formats }).first || super" name_clause = if name default_behavior else @@ -316,7 +316,7 @@ module ActionView end self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 - def _layout + def _layout(formats) if _conditional_layout? #{layout_definition} else @@ -372,7 +372,7 @@ module ActionView end # This will be overwritten by _write_layout_method - def _layout; end + def _layout(*); end # Determine the layout for a given name, taking into account the name type. # @@ -382,8 +382,8 @@ module ActionView case name when String then _normalize_layout(name) when Proc then name - when true then Proc.new { _default_layout(true) } - when :default then Proc.new { _default_layout(false) } + when true then Proc.new { |formats| _default_layout(formats, true) } + when :default then Proc.new { |formats| _default_layout(formats, false) } when false, nil then nil else raise ArgumentError, @@ -399,14 +399,15 @@ module ActionView # Optionally raises an exception if the layout could not be found. # # ==== Parameters + # * <tt>formats</tt> - The formats accepted to this layout # * <tt>require_layout</tt> - If set to true and layout is not found, # an ArgumentError exception is raised (defaults to false) # # ==== Returns # * <tt>template</tt> - The template object for the default layout (or nil) - def _default_layout(require_layout = false) + def _default_layout(formats, require_layout = false) begin - value = _layout if action_has_layout? + value = _layout(formats) if action_has_layout? rescue NameError => e raise e, "Could not render layout: #{e.message}" end diff --git a/actionview/lib/action_view/lookup_context.rb b/actionview/lib/action_view/lookup_context.rb index f4a10aa393..fba9a44cb1 100644 --- a/actionview/lib/action_view/lookup_context.rb +++ b/actionview/lib/action_view/lookup_context.rb @@ -229,21 +229,5 @@ module ActionView super(default_locale) end - - # Uses the first format in the formats array for layout lookup. - def with_layout_format - if formats.size == 1 - yield - else - old_formats = formats - _set_detail(:formats, formats[0,1]) - - begin - yield - ensure - _set_detail(:formats, old_formats) - end - end - end end end diff --git a/actionview/lib/action_view/renderer/partial_renderer.rb b/actionview/lib/action_view/renderer/partial_renderer.rb index 780fdabbd1..1f9e960488 100644 --- a/actionview/lib/action_view/renderer/partial_renderer.rb +++ b/actionview/lib/action_view/renderer/partial_renderer.rb @@ -520,7 +520,7 @@ module ActionView def retrieve_variable(path, as) variable = as || begin - base = path[-1] == "/" ? "" : File.basename(path) + base = path[-1] == "/".freeze ? "".freeze : File.basename(path) raise_invalid_identifier(path) unless base =~ /\A_?(.*)(?:\.\w+)*\z/ $1.to_sym end diff --git a/actionview/lib/action_view/renderer/streaming_template_renderer.rb b/actionview/lib/action_view/renderer/streaming_template_renderer.rb index 3ab2cd36fc..f38e2764d0 100644 --- a/actionview/lib/action_view/renderer/streaming_template_renderer.rb +++ b/actionview/lib/action_view/renderer/streaming_template_renderer.rb @@ -47,7 +47,7 @@ module ActionView return [super] unless layout_name && template.supports_streaming? locals ||= {} - layout = layout_name && find_layout(layout_name, locals.keys) + layout = layout_name && find_layout(layout_name, locals.keys, [formats.first]) Body.new do |buffer| delayed_render(buffer, template, layout, @view, locals) diff --git a/actionview/lib/action_view/renderer/template_renderer.rb b/actionview/lib/action_view/renderer/template_renderer.rb index dbb4855e39..75217e1630 100644 --- a/actionview/lib/action_view/renderer/template_renderer.rb +++ b/actionview/lib/action_view/renderer/template_renderer.rb @@ -57,7 +57,7 @@ module ActionView end def render_with_layout(path, locals) #:nodoc: - layout = path && find_layout(path, locals.keys) + layout = path && find_layout(path, locals.keys, [formats.first]) content = yield(layout) if layout @@ -72,27 +72,28 @@ module ActionView # This is the method which actually finds the layout using details in the lookup # context object. If no layout is found, it checks if at least a layout with # the given name exists across all details before raising the error. - def find_layout(layout, keys) - with_layout_format { resolve_layout(layout, keys) } + def find_layout(layout, keys, formats) + resolve_layout(layout, keys, formats) end - def resolve_layout(layout, keys) + def resolve_layout(layout, keys, formats) + details = @details.dup + details[:formats] = formats + case layout when String begin if layout =~ /^\// - with_fallbacks { find_template(layout, nil, false, keys, @details) } + with_fallbacks { find_template(layout, nil, false, keys, details) } else - find_template(layout, nil, false, keys, @details) + find_template(layout, nil, false, keys, details) end rescue ActionView::MissingTemplate all_details = @details.merge(:formats => @lookup_context.default_formats) raise unless template_exists?(layout, nil, false, keys, all_details) end when Proc - resolve_layout(layout.call, keys) - when FalseClass - nil + resolve_layout(layout.call(formats), keys, formats) else layout end diff --git a/actionview/lib/action_view/template.rb b/actionview/lib/action_view/template.rb index 1ce9f94b13..e232808dcb 100644 --- a/actionview/lib/action_view/template.rb +++ b/actionview/lib/action_view/template.rb @@ -154,7 +154,7 @@ module ActionView # we use a bang in this instrumentation because you don't want to # consume this in production. This is only slow if it's being listened to. def render(view, locals, buffer=nil, &block) - instrument("!render_template") do + instrument("!render_template".freeze) do compile!(view) view.send(method_name, locals, buffer, &block) end @@ -348,7 +348,12 @@ module ActionView def instrument(action, &block) payload = { virtual_path: @virtual_path, identifier: @identifier } - ActiveSupport::Notifications.instrument("#{action}.action_view", payload, &block) + case action + when "!render_template".freeze + ActiveSupport::Notifications.instrument("!render_template.action_view".freeze, payload, &block) + else + ActiveSupport::Notifications.instrument("#{action}.action_view".freeze, payload, &block) + end end EXPLICIT_COLLECTION = /# Template Collection: (?<resource_name>\w+)/ diff --git a/actionview/lib/action_view/test_case.rb b/actionview/lib/action_view/test_case.rb index c4bc26ca8a..f6b5696a13 100644 --- a/actionview/lib/action_view/test_case.rb +++ b/actionview/lib/action_view/test_case.rb @@ -263,9 +263,15 @@ module ActionView end def method_missing(selector, *args) - if @controller.respond_to?(:_routes) && - ( @controller._routes.named_routes.route_defined?(selector) || - @controller._routes.mounted_helpers.method_defined?(selector) ) + begin + routes = @controller.respond_to?(:_routes) && @controller._routes + rescue + # Dont call routes, if there is an error on _routes call + end + + if routes && + ( routes.named_routes.route_defined?(selector) || + routes.mounted_helpers.method_defined?(selector) ) @controller.__send__(selector, *args) else super |