From cece50d3a6b432f848ca04a92da331f8b032d51f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Thu, 5 May 2016 11:18:10 -0500 Subject: Move protected instance variable to the right place There were a lot of protected instance variables in AbsctractController::Rendering that were related to Action Controller and Action View. Moving to ActionController::Base's protected instance list we make it closer to where they are really defined. --- actionpack/lib/abstract_controller/rendering.rb | 4 +--- actionpack/lib/action_controller/base.rb | 7 ++++--- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 9f192c54f7..a6fb0dbe1d 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -60,9 +60,7 @@ module AbstractController end DEFAULT_PROTECTED_INSTANCE_VARIABLES = Set.new %i( - @_action_name @_response_body @_formats @_prefixes @_config - @_view_context_class @_view_renderer @_lookup_context - @_routes @_db_runtime + @_action_name @_response_body @_formats @_prefixes ) # This method should return a hash with assigns. diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 56a8d2e5f4..54dc6f48c5 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -251,9 +251,10 @@ module ActionController setup_renderer! # Define some internal variables that should not be propagated to the view. - PROTECTED_IVARS = AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + [ - :@_params, :@_response, :@_request, - :@_view_runtime, :@_stream, :@_url_options, :@_action_has_layout ] + PROTECTED_IVARS = AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + %i( + @_params @_response @_request @_config @_url_options @_action_has_layout @_view_context_class + @_view_renderer @_lookup_context @_routes @_view_runtime @_db_runtime + ) def _protected_ivars # :nodoc: PROTECTED_IVARS -- cgit v1.2.3 From 541a51ecf8ee04f956b7d8efb13935640aa831ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Thu, 5 May 2016 12:02:28 -0500 Subject: Implement helpers proxy in controller instance level It is a common pattern in the Rails community that when people want to :xa use any kind of helper that is defined inside app/helpers they includes the helper module inside the controller like: module UserHelper def my_user_helper # ... end end class UsersController < ApplicationController include UserHelper def index render inline: my_user_helper end end This has problem because the helper can't access anything that is defined in the view level context class. Also all public methods of the helper become available in the controller what can lead to undesirable methods being routed and behaving as actions. Also if you helper depends on other helpers or even Action View helpers you need to include each one of these dependencies in your controller otherwise your helper is not going to work. We already have a helpers proxy at controller class level but that proxy doesn't have access to the instance variables defined in the controller. With this new instance level helper proxy users can reuse helpers in the controller without having to include the modules and with access to instance variables defined in the controller. class UsersController < ApplicationController def index render inline: helpers.my_user_helper end end --- actionpack/CHANGELOG.md | 6 ++++++ actionpack/lib/action_controller/base.rb | 2 +- actionpack/lib/action_controller/metal/helpers.rb | 7 ++++++- actionpack/test/controller/helper_test.rb | 16 ++++++++++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 85d2b14285..9b902b46a2 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,3 +1,9 @@ +* Add `ActionController#helpers` to get access to the view context in the controller + level. + + *Rafael Mendonça França* + + ## Rails 5.0.0.beta4 (April 27, 2016) ## * Routing: Refactor `:action` default handling to ensure that path diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 54dc6f48c5..d546d7260c 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -253,7 +253,7 @@ module ActionController # Define some internal variables that should not be propagated to the view. PROTECTED_IVARS = AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + %i( @_params @_response @_request @_config @_url_options @_action_has_layout @_view_context_class - @_view_renderer @_lookup_context @_routes @_view_runtime @_db_runtime + @_view_renderer @_lookup_context @_routes @_view_runtime @_db_runtime @_helper_proxy ) def _protected_ivars # :nodoc: diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb index d3853e2e83..22493dea50 100644 --- a/actionpack/lib/action_controller/metal/helpers.rb +++ b/actionpack/lib/action_controller/metal/helpers.rb @@ -5,7 +5,7 @@ module ActionController # # In addition to using the standard template helpers provided, creating custom helpers to # extract complicated logic or reusable functionality is strongly encouraged. By default, each controller - # will include all helpers. These helpers are only accessible on the controller through .helpers + # will include all helpers. These helpers are only accessible on the controller through #helpers # # In previous versions of \Rails the controller will include a helper which # matches the name of the controller, e.g., MyController will automatically @@ -113,5 +113,10 @@ module ActionController all_helpers_from_path(helpers_path) end end + + # Provides a proxy to access helpers methods from outside the view. + def helpers + @_helper_proxy ||= view_context + end end end diff --git a/actionpack/test/controller/helper_test.rb b/actionpack/test/controller/helper_test.rb index feb882a2b3..ef85e141a0 100644 --- a/actionpack/test/controller/helper_test.rb +++ b/actionpack/test/controller/helper_test.rb @@ -207,6 +207,22 @@ class HelperTest < ActiveSupport::TestCase assert methods.include?(:foobar) end + def test_helper_proxy_in_instance + methods = AllHelpersController.new.helpers.methods + + # Action View + assert_includes methods, :pluralize + + # abc_helper.rb + assert_includes methods, :bare_a + + # fun/games_helper.rb + assert_includes methods, :stratego + + # fun/pdf_helper.rb + assert_includes methods, :foobar + end + def test_helper_proxy_config AllHelpersController.config.my_var = 'smth' -- cgit v1.2.3