From a5d80f84d269bba6b0f0802612f29df1ee09d720 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Thu, 18 Mar 2010 18:12:04 -0700 Subject: Each controller class has it's own view context subclass. This removes the need for ActionView::Base.for_controller --- actionpack/lib/abstract_controller/helpers.rb | 10 +------ actionpack/lib/abstract_controller/rendering.rb | 28 ++++++++++++++++--- .../action_dispatch/testing/assertions/routing.rb | 7 +++-- actionpack/lib/action_view/base.rb | 32 ---------------------- actionpack/lib/action_view/context.rb | 2 -- 5 files changed, 29 insertions(+), 50 deletions(-) diff --git a/actionpack/lib/abstract_controller/helpers.rb b/actionpack/lib/abstract_controller/helpers.rb index f875213afb..53cf6b3931 100644 --- a/actionpack/lib/abstract_controller/helpers.rb +++ b/actionpack/lib/abstract_controller/helpers.rb @@ -6,16 +6,10 @@ module AbstractController include Rendering - def self.next_serial - @helper_serial ||= 0 - @helper_serial += 1 - end - included do - class_attribute :_helpers, :_helper_serial + class_attribute :_helpers delegate :_helpers, :to => :'self.class' self._helpers = Module.new - self._helper_serial = ::AbstractController::Helpers.next_serial end module ClassMethods @@ -95,8 +89,6 @@ module AbstractController # helper(:three, BlindHelper) { def mice() 'mice' end } # def helper(*args, &block) - self._helper_serial = AbstractController::Helpers.next_serial + 1 - modules_for_helpers(args).each do |mod| add_template_helper(mod) end diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 402ad7c8d7..58d339d563 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -42,18 +42,38 @@ module AbstractController I18n.config = old_config end + module ClassMethods + def view_context_class + @view_context_class ||= begin + controller = self + Class.new(ActionView::Base) do + if controller.respond_to?(:_helpers) + include controller._helpers + # TODO: Fix RJS to not require this + self.helpers = controller._helpers + end + end + end + end + end + + attr_writer :view_context_class + + def view_context_class + @view_context_class || self.class.view_context_class + end + # An instance of a view class. The default view class is ActionView::Base # # The view class must have the following methods: - # View.for_controller[controller] + # View.new[lookup_context, assigns, controller] # Create a new ActionView instance for a controller - # View#render_template[options] + # View#render[options] # Returns String with the rendered template # # Override this method in a module to change the default behavior. def view_context - klass = ActionView::Base.for_controller(self) - klass.new(lookup_context, view_assigns, self) + view_context_class.new(lookup_context, view_assigns, self) end # Normalize arguments, options and then delegates render_to_body and diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb index de833bb3ca..1bb81ede3b 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb @@ -153,15 +153,16 @@ module ActionDispatch # # TODO: Make this unnecessary if @controller - @controller.singleton_class.send(:include, @router.url_helpers) - @controller.class._helper_serial = AbstractController::Helpers.next_serial + 1 + @controller.singleton_class.send(:include, _router.url_helpers) + @controller.view_context_class = Class.new(@controller.view_context_class) do + include _router.url_helpers + end end yield @router ensure @router = old_routes if @controller @controller = old_controller - @controller.class._helper_serial = AbstractController::Helpers.next_serial + 1 if @controller end end diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index b82c6a8203..66af693cde 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -220,38 +220,6 @@ module ActionView #:nodoc: ActionView::PathSet.new(Array.wrap(value)) end - def self.for_controller(controller) - @views ||= {} - - # TODO: Decouple this so helpers are a separate concern in AV just like - # they are in AC. - if controller.class.respond_to?(:_helper_serial) - klass = @views[controller.class._helper_serial] ||= Class.new(self) do - # Try to make stack traces clearer - class_eval <<-ruby_eval, __FILE__, __LINE__ + 1 - def self.name - "ActionView for #{controller.class}" - end - - def inspect - "#<#{self.class.name}>" - end - ruby_eval - - if controller.respond_to?(:_helpers) - include controller._helpers - self.helpers = controller._helpers - end - - if controller.respond_to?(:_router) - include controller._router.url_helpers - end - end - else - klass = self - end - end - def initialize(lookup_context = nil, assigns_for_first_render = {}, controller = nil, formats = nil) #:nodoc: @config = nil @assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) } diff --git a/actionpack/lib/action_view/context.rb b/actionpack/lib/action_view/context.rb index df078a7151..61d2e702a7 100644 --- a/actionpack/lib/action_view/context.rb +++ b/actionpack/lib/action_view/context.rb @@ -10,8 +10,6 @@ module ActionView # In order to work with ActionController, a Context # must implement: # - # Context.for_controller[controller] Create a new ActionView instance for a - # controller # Context#render_partial[options] # - responsible for setting options[:_template] # - Returns String with the rendered partial -- cgit v1.2.3