aboutsummaryrefslogtreecommitdiffstats
path: root/actionview
diff options
context:
space:
mode:
Diffstat (limited to 'actionview')
-rw-r--r--actionview/CHANGELOG.md22
-rw-r--r--actionview/lib/action_view/helpers/form_helper.rb6
-rw-r--r--actionview/lib/action_view/helpers/translation_helper.rb3
-rw-r--r--actionview/lib/action_view/routing_url_for.rb8
-rw-r--r--actionview/lib/action_view/template/resolver.rb28
-rw-r--r--actionview/lib/action_view/view_paths.rb41
-rw-r--r--actionview/test/actionpack/abstract/abstract_controller_test.rb48
-rw-r--r--actionview/test/activerecord/polymorphic_routes_test.rb85
-rw-r--r--actionview/test/template/sanitize_helper_test.rb2
-rw-r--r--actionview/test/template/test_test.rb2
-rw-r--r--actionview/test/template/translation_helper_test.rb6
11 files changed, 205 insertions, 46 deletions
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md
index 36028122d1..147e5b47db 100644
--- a/actionview/CHANGELOG.md
+++ b/actionview/CHANGELOG.md
@@ -1,4 +1,15 @@
-* Take label values into account when doing I18n lookups for model attributes.
+* Allow custom `:host` option to be passed to `asset_url` helper that
+ overwrites `config.action_controller.asset_host` for particular asset.
+
+ *Hubert Łępicki*
+
+* Deprecate `AbstractController::Base.parent_prefixes`.
+ Override `AbstractController::Base.local_prefixes` when you want to change
+ where to find views.
+
+ *Nick Sutterer*
+
+* Take label values into account when doing I18n lookups for model attributes.
The following:
@@ -20,9 +31,11 @@
* Change `asset_path` to use File.join to create proper paths:
+ Before:
+
https://some.host.com//assets/some.js
- becomes
+ After:
https://some.host.com/assets/some.js
@@ -87,9 +100,4 @@
*Piotr Chmolowski, Łukasz Strzałkowski*
-* Allow custom `:host` option to be passed to `asset_url` helper that
- overwrites `config.action_controller.asset_host` for particular asset.
-
- *Hubert Łępicki*
-
Please check [4-1-stable](https://github.com/rails/rails/blob/4-1-stable/actionview/CHANGELOG.md) for previous changes.
diff --git a/actionview/lib/action_view/helpers/form_helper.rb b/actionview/lib/action_view/helpers/form_helper.rb
index 22bfd87d85..180c4a62bf 100644
--- a/actionview/lib/action_view/helpers/form_helper.rb
+++ b/actionview/lib/action_view/helpers/form_helper.rb
@@ -449,7 +449,11 @@ module ActionView
method: method
)
- options[:url] ||= polymorphic_path(record, format: options.delete(:format))
+ options[:url] ||= if options.key?(:format)
+ polymorphic_path(record, format: options.delete(:format))
+ else
+ polymorphic_path(record, {})
+ end
end
private :apply_form_for_options!
diff --git a/actionview/lib/action_view/helpers/translation_helper.rb b/actionview/lib/action_view/helpers/translation_helper.rb
index 0bc40874d9..17ec6a40bf 100644
--- a/actionview/lib/action_view/helpers/translation_helper.rb
+++ b/actionview/lib/action_view/helpers/translation_helper.rb
@@ -7,7 +7,7 @@ module ActionView
module TranslationHelper
# Delegates to <tt>I18n#translate</tt> but also performs three additional functions.
#
- # First, it will ensure that any thrown +MissingTranslation+ messages will be turned
+ # First, it will ensure that any thrown +MissingTranslation+ messages will be turned
# into inline spans that:
#
# * have a "translation-missing" class set,
@@ -34,6 +34,7 @@ module ActionView
# naming convention helps to identify translations that include HTML tags so that
# you know what kind of output to expect when you call translate in a template.
def translate(key, options = {})
+ options = options.dup
options[:default] = wrap_translate_defaults(options[:default]) if options[:default]
# If the user has specified rescue_format then pass it all through, otherwise use
diff --git a/actionview/lib/action_view/routing_url_for.rb b/actionview/lib/action_view/routing_url_for.rb
index b9e4b590e7..881a123572 100644
--- a/actionview/lib/action_view/routing_url_for.rb
+++ b/actionview/lib/action_view/routing_url_for.rb
@@ -1,3 +1,5 @@
+require 'action_dispatch/routing/polymorphic_routes'
+
module ActionView
module RoutingUrlFor
@@ -83,10 +85,14 @@ module ActionView
super({ :only_path => options[:host].nil? }.merge!(options.symbolize_keys))
when :back
_back_url
+ when Symbol
+ ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.path.handle_string_call self, options
when Array
polymorphic_path(options, options.extract_options!)
+ when Class
+ ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.path.handle_class_call self, options
else
- polymorphic_path(options)
+ ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.path.handle_model_call self, options
end
end
diff --git a/actionview/lib/action_view/template/resolver.rb b/actionview/lib/action_view/template/resolver.rb
index 05f0c301e7..189086132e 100644
--- a/actionview/lib/action_view/template/resolver.rb
+++ b/actionview/lib/action_view/template/resolver.rb
@@ -181,13 +181,7 @@ module ActionView
def query(path, details, formats)
query = build_query(path, details)
- # deals with case-insensitive file systems.
- sanitizer = Hash.new { |h,dir| h[dir] = Dir["#{dir}/*"] }
-
- template_paths = Dir[query].reject { |filename|
- File.directory?(filename) ||
- !sanitizer[File.dirname(filename)].include?(filename)
- }
+ template_paths = find_template_paths query
template_paths.map { |template|
handler, format, variant = extract_handler_and_format_and_variant(template, formats)
@@ -202,6 +196,26 @@ module ActionView
}
end
+ if File.const_defined? :FNM_EXTGLOB
+ def find_template_paths(query)
+ Dir[query].reject { |filename|
+ File.directory?(filename) ||
+ # deals with case-insensitive file systems.
+ !File.fnmatch(query, filename, File::FNM_EXTGLOB)
+ }
+ end
+ else
+ def find_template_paths(query)
+ # deals with case-insensitive file systems.
+ sanitizer = Hash.new { |h,dir| h[dir] = Dir["#{dir}/*"] }
+
+ Dir[query].reject { |filename|
+ File.directory?(filename) ||
+ !sanitizer[File.dirname(filename)].include?(filename)
+ }
+ end
+ end
+
# Helper for building query glob string based on resolver's pattern.
def build_query(path, details)
query = @pattern.dup
diff --git a/actionview/lib/action_view/view_paths.rb b/actionview/lib/action_view/view_paths.rb
index 6c349feb1d..80a41f2418 100644
--- a/actionview/lib/action_view/view_paths.rb
+++ b/actionview/lib/action_view/view_paths.rb
@@ -14,27 +14,38 @@ module ActionView
:locale, :locale=, :to => :lookup_context
module ClassMethods
- def parent_prefixes
- @parent_prefixes ||= begin
- parent_controller = superclass
- prefixes = []
-
- until parent_controller.abstract?
- prefixes << parent_controller.controller_path
- parent_controller = parent_controller.superclass
- end
+ def _prefixes # :nodoc:
+ @_prefixes ||= begin
+ deprecated_prefixes = handle_deprecated_parent_prefixes
+ if deprecated_prefixes
+ deprecated_prefixes
+ else
+ return local_prefixes if superclass.abstract?
- prefixes
+ local_prefixes + superclass._prefixes
+ end
end
end
+
+ private
+
+ # Override this method in your controller if you want to change paths prefixes for finding views.
+ # Prefixes defined here will still be added to parents' <tt>._prefixes</tt>.
+ def local_prefixes
+ [controller_path]
+ end
+
+ def handle_deprecated_parent_prefixes # TODO: remove in 4.3/5.0.
+ return unless respond_to?(:parent_prefixes)
+
+ ActiveSupport::Deprecation.warn "Overriding ActionController::Base::parent_prefixes is deprecated, override .local_prefixes instead."
+ local_prefixes + parent_prefixes
+ end
end
# The prefixes used in render "foo" shortcuts.
- def _prefixes
- @_prefixes ||= begin
- parent_prefixes = self.class.parent_prefixes
- parent_prefixes.dup.unshift(controller_path)
- end
+ def _prefixes # :nodoc:
+ self.class._prefixes
end
# LookupContext is the object responsible to hold all information required to lookup
diff --git a/actionview/test/actionpack/abstract/abstract_controller_test.rb b/actionview/test/actionpack/abstract/abstract_controller_test.rb
index 40d3b17131..e653b12d32 100644
--- a/actionview/test/actionpack/abstract/abstract_controller_test.rb
+++ b/actionview/test/actionpack/abstract/abstract_controller_test.rb
@@ -150,6 +150,54 @@ module AbstractController
end
end
+ class OverridingLocalPrefixes < AbstractController::Base
+ include AbstractController::Rendering
+ include ActionView::Rendering
+ append_view_path File.expand_path(File.join(File.dirname(__FILE__), "views"))
+
+ def index
+ render
+ end
+
+ def self.local_prefixes
+ # this would usually return "abstract_controller/testing/overriding_local_prefixes"
+ super + ["abstract_controller/testing/me3"]
+ end
+
+ class Inheriting < self
+ end
+ end
+
+ class OverridingLocalPrefixesTest < ActiveSupport::TestCase # TODO: remove me in 5.0/4.3.
+ test "overriding .local_prefixes adds prefix" do
+ @controller = OverridingLocalPrefixes.new
+ @controller.process(:index)
+ assert_equal "Hello from me3/index.erb", @controller.response_body
+ end
+
+ test ".local_prefixes is inherited" do
+ @controller = OverridingLocalPrefixes::Inheriting.new
+ @controller.process(:index)
+ assert_equal "Hello from me3/index.erb", @controller.response_body
+ end
+ end
+
+ class DeprecatedParentPrefixes < OverridingLocalPrefixes
+ def self.parent_prefixes
+ ["abstract_controller/testing/me3"]
+ end
+ end
+
+ class DeprecatedParentPrefixesTest < ActiveSupport::TestCase # TODO: remove me in 5.0/4.3.
+ test "overriding .parent_prefixes is deprecated" do
+ @controller = DeprecatedParentPrefixes.new
+ assert_deprecated do
+ @controller.process(:index)
+ end
+ assert_equal "Hello from me3/index.erb", @controller.response_body
+ end
+ end
+
# Test rendering with layouts
# ====
# self._layout is used when defined
diff --git a/actionview/test/activerecord/polymorphic_routes_test.rb b/actionview/test/activerecord/polymorphic_routes_test.rb
index a42888d873..fef27ef492 100644
--- a/actionview/test/activerecord/polymorphic_routes_test.rb
+++ b/actionview/test/activerecord/polymorphic_routes_test.rb
@@ -75,6 +75,9 @@ class PolymorphicRoutesTest < ActionController::TestCase
end
def assert_url(url, args)
+ host = self.class.default_url_options[:host]
+
+ assert_equal url.sub(/http:\/\/#{host}/, ''), polymorphic_path(args)
assert_equal url, polymorphic_url(args)
assert_equal url, url_for(args)
end
@@ -96,8 +99,7 @@ class PolymorphicRoutesTest < ActionController::TestCase
def test_symbol
with_test_routes do
- assert_equal "http://example.com/projects", polymorphic_url(:projects)
- assert_equal "http://example.com/projects", url_for(:projects)
+ assert_url "http://example.com/projects", :projects
end
end
@@ -129,6 +131,23 @@ class PolymorphicRoutesTest < ActionController::TestCase
end
end
+ def test_polymorphic_url_with_2_objects
+ with_namespaced_routes(:blog) do
+ @blog_blog.save
+ @blog_post.save
+ assert_equal "http://example.com/blogs/#{@blog_blog.id}/posts/#{@blog_post.id}", polymorphic_url([@blog_blog, @blog_post])
+ end
+ end
+
+ def test_polymorphic_url_with_3_objects
+ with_namespaced_routes(:blog) do
+ @blog_blog.save
+ @blog_post.save
+ @fax.save
+ assert_equal "http://example.com/blogs/#{@blog_blog.id}/posts/#{@blog_post.id}/faxes/#{@fax.id}", polymorphic_url([@blog_blog, @blog_post, @fax])
+ end
+ end
+
def test_namespaced_model_with_nested_resources
with_namespaced_routes(:blog) do
@blog_post.save
@@ -183,6 +202,19 @@ class PolymorphicRoutesTest < ActionController::TestCase
end
end
+ def test_with_class_list_of_one
+ with_test_routes do
+ assert_url "http://example.com/projects", [@project.class]
+ end
+ end
+
+ def test_class_with_options
+ with_test_routes do
+ assert_equal "http://example.com/projects?foo=bar", polymorphic_url(@project.class, { :foo => :bar })
+ assert_equal "/projects?foo=bar", polymorphic_path(@project.class, { :foo => :bar })
+ end
+ end
+
def test_with_new_record
with_test_routes do
assert_url "http://example.com/projects", @project
@@ -191,14 +223,20 @@ class PolymorphicRoutesTest < ActionController::TestCase
def test_new_record_arguments
params = nil
- extend Module.new {
- define_method("projects_url") { |*args|
- params = args
- super(*args)
- }
- }
with_test_routes do
+ extend Module.new {
+ define_method("projects_url") { |*args|
+ params = args
+ super(*args)
+ }
+
+ define_method("projects_path") { |*args|
+ params = args
+ super(*args)
+ }
+ }
+
assert_url "http://example.com/projects", @project
assert_equal [], params
end
@@ -389,6 +427,12 @@ class PolymorphicRoutesTest < ActionController::TestCase
end
end
+ def test_with_array_containing_single_string_name
+ with_test_routes do
+ assert_url "http://example.com/projects", ["projects"]
+ end
+ end
+
def test_with_array_containing_symbols
with_test_routes do
assert_url "http://example.com/series/new", [:new, :series]
@@ -543,13 +587,15 @@ class PolymorphicRoutesTest < ActionController::TestCase
set.draw do
scope(:module => name) do
resources :blogs do
- resources :posts
+ resources :posts do
+ resources :faxes
+ end
end
resources :posts
end
end
- self.class.send(:include, @routes.url_helpers)
+ extend @routes.url_helpers
yield
end
end
@@ -571,7 +617,7 @@ class PolymorphicRoutesTest < ActionController::TestCase
resources :model_delegates
end
- self.class.send(:include, @routes.url_helpers)
+ extend @routes.url_helpers
yield
end
end
@@ -593,7 +639,7 @@ class PolymorphicRoutesTest < ActionController::TestCase
end
end
- self.class.send(:include, @routes.url_helpers)
+ extend @routes.url_helpers
yield
end
end
@@ -612,8 +658,21 @@ class PolymorphicRoutesTest < ActionController::TestCase
end
end
- self.class.send(:include, @routes.url_helpers)
+ extend @routes.url_helpers
yield
end
end
end
+
+class PolymorphicPathRoutesTest < PolymorphicRoutesTest
+ include ActionView::RoutingUrlFor
+ include ActionView::Context
+
+ attr_accessor :controller
+
+ def assert_url(url, args)
+ host = self.class.default_url_options[:host]
+
+ assert_equal url.sub(/http:\/\/#{host}/, ''), url_for(args)
+ end
+end
diff --git a/actionview/test/template/sanitize_helper_test.rb b/actionview/test/template/sanitize_helper_test.rb
index 12d5260a9d..f7c8f36b78 100644
--- a/actionview/test/template/sanitize_helper_test.rb
+++ b/actionview/test/template/sanitize_helper_test.rb
@@ -1,6 +1,6 @@
require 'abstract_unit'
-# The exhaustive tests are in test/controller/html/sanitizer_test.rb.
+# The exhaustive tests are in test/template/html-scanner/sanitizer_test.rb
# This tests the that the helpers hook up correctly to the sanitizer classes.
class SanitizeHelperTest < ActionView::TestCase
tests ActionView::Helpers::SanitizeHelper
diff --git a/actionview/test/template/test_test.rb b/actionview/test/template/test_test.rb
index 5721ee6c6f..88bac85039 100644
--- a/actionview/test/template/test_test.rb
+++ b/actionview/test/template/test_test.rb
@@ -39,6 +39,8 @@ class PeopleHelperTest < ActionView::TestCase
with_test_route_set do
person = Struct.new(:name) {
extend ActiveModel::Naming
+ def to_model; self; end
+ def persisted?; true; end
def self.name; 'Mocha::Mock'; end
}.new "David"
diff --git a/actionview/test/template/translation_helper_test.rb b/actionview/test/template/translation_helper_test.rb
index c4770840fb..a9d5ea7345 100644
--- a/actionview/test/template/translation_helper_test.rb
+++ b/actionview/test/template/translation_helper_test.rb
@@ -151,4 +151,10 @@ class TranslationHelperTest < ActiveSupport::TestCase
translation = translate(:'translations.missing', default: ['A Generic String', 'Second generic string'])
assert_equal 'A Generic String', translation
end
+
+ def test_translate_does_not_change_options
+ options = {}
+ translate(:'translations.missing', options)
+ assert_equal({}, options)
+ end
end