From c740ebdaf580c8c9772a9099c7a9c11ef3105f3a Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 16 Jan 2019 17:28:03 -0800 Subject: [PATCH] Always evaluate views against an ActionView::Base Methods created by views should always be evaluated against an AV::Base instance. This way we can extract and refactor things in to classes. --- actionview/lib/action_view/base.rb | 7 +++++++ actionview/lib/action_view/template.rb | 6 +++--- .../lib/action_view/template/handlers/erb/erubi.rb | 10 ++++++---- actionview/test/abstract_unit.rb | 2 +- actionview/test/template/template_test.rb | 2 +- 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/actionview/lib/action_view/base.rb b/actionview/lib/action_view/base.rb index d41fe2a608..4318791760 100644 --- a/actionview/lib/action_view/base.rb +++ b/actionview/lib/action_view/base.rb @@ -210,6 +210,13 @@ module ActionView #:nodoc: _prepare_context end + def run(method, locals, buffer, &block) + _old_output_buffer = @output_buffer + send(method, locals, buffer, &block) + ensure + @output_buffer = _old_output_buffer + end + ActiveSupport.run_load_hooks(:action_view, self) end end diff --git a/actionview/lib/action_view/template.rb b/actionview/lib/action_view/template.rb index da9f20990f..ed680df4c6 100644 --- a/actionview/lib/action_view/template.rb +++ b/actionview/lib/action_view/template.rb @@ -158,7 +158,7 @@ module ActionView def render(view, locals, buffer = ActionView::OutputBuffer.new, &block) instrument_render_template do compile!(view) - view.send(method_name, locals, buffer, &block) + view.run(method_name, locals, buffer, &block) end rescue => e handle_render_error(view, e) @@ -301,9 +301,9 @@ module ActionView # encoding of the code source = +<<-end_src def #{method_name}(local_assigns, output_buffer) - _old_virtual_path, @virtual_path = @virtual_path, #{@virtual_path.inspect};_old_output_buffer = @output_buffer;#{locals_code};#{code} + _old_virtual_path, @virtual_path = @virtual_path, #{@virtual_path.inspect};#{locals_code};#{code} ensure - @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer + @virtual_path = _old_virtual_path end end_src diff --git a/actionview/lib/action_view/template/handlers/erb/erubi.rb b/actionview/lib/action_view/template/handlers/erb/erubi.rb index d379d7ec12..d0e87e6e7f 100644 --- a/actionview/lib/action_view/template/handlers/erb/erubi.rb +++ b/actionview/lib/action_view/template/handlers/erb/erubi.rb @@ -22,10 +22,12 @@ module ActionView end def evaluate(action_view_erb_handler_context) - pr = eval("proc { #{@src} }", binding, @filename || "(erubi)") - # Double assignment to eliminate -w warnings - output_buffer = output_buffer = ActionView::OutputBuffer.new - action_view_erb_handler_context.instance_eval(&pr) + src = @src + view = Class.new(ActionView::Base) { + include action_view_erb_handler_context._routes.url_helpers + class_eval("define_method(:_template) { |local_assigns, output_buffer| #{src} }", @filename || "(erubi)", 0) + }.new(action_view_erb_handler_context) + view.run(:_template, {}, ActionView::OutputBuffer.new) end private diff --git a/actionview/test/abstract_unit.rb b/actionview/test/abstract_unit.rb index f90626ad9e..d71944e938 100644 --- a/actionview/test/abstract_unit.rb +++ b/actionview/test/abstract_unit.rb @@ -61,7 +61,7 @@ module RenderERBUtils ActionView::Template::Handlers::ERB, {}) - template.render(self, {}).strip + template.render(ActionView::Base.new, {}).strip end end diff --git a/actionview/test/template/template_test.rb b/actionview/test/template/template_test.rb index b348d1f17b..8257d97b7c 100644 --- a/actionview/test/template/template_test.rb +++ b/actionview/test/template/template_test.rb @@ -18,7 +18,7 @@ class TestERBTemplate < ActiveSupport::TestCase attr_accessor :formats end - class Context + class Context < ActionView::Base def initialize @output_buffer = "original" @virtual_path = nil