1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

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.
This commit is contained in:
Aaron Patterson 2019-01-16 17:28:03 -08:00
parent ccfa01c36e
commit c740ebdaf5
No known key found for this signature in database
GPG key ID: 953170BCB4FFAFC6
5 changed files with 18 additions and 9 deletions

View file

@ -210,6 +210,13 @@ module ActionView #:nodoc:
_prepare_context _prepare_context
end 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) ActiveSupport.run_load_hooks(:action_view, self)
end end
end end

View file

@ -158,7 +158,7 @@ module ActionView
def render(view, locals, buffer = ActionView::OutputBuffer.new, &block) def render(view, locals, buffer = ActionView::OutputBuffer.new, &block)
instrument_render_template do instrument_render_template do
compile!(view) compile!(view)
view.send(method_name, locals, buffer, &block) view.run(method_name, locals, buffer, &block)
end end
rescue => e rescue => e
handle_render_error(view, e) handle_render_error(view, e)
@ -301,9 +301,9 @@ module ActionView
# encoding of the code # encoding of the code
source = +<<-end_src source = +<<-end_src
def #{method_name}(local_assigns, output_buffer) 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 ensure
@virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer @virtual_path = _old_virtual_path
end end
end_src end_src

View file

@ -22,10 +22,12 @@ module ActionView
end end
def evaluate(action_view_erb_handler_context) def evaluate(action_view_erb_handler_context)
pr = eval("proc { #{@src} }", binding, @filename || "(erubi)") src = @src
# Double assignment to eliminate -w warnings view = Class.new(ActionView::Base) {
output_buffer = output_buffer = ActionView::OutputBuffer.new include action_view_erb_handler_context._routes.url_helpers
action_view_erb_handler_context.instance_eval(&pr) 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 end
private private

View file

@ -61,7 +61,7 @@ module RenderERBUtils
ActionView::Template::Handlers::ERB, ActionView::Template::Handlers::ERB,
{}) {})
template.render(self, {}).strip template.render(ActionView::Base.new, {}).strip
end end
end end

View file

@ -18,7 +18,7 @@ class TestERBTemplate < ActiveSupport::TestCase
attr_accessor :formats attr_accessor :formats
end end
class Context class Context < ActionView::Base
def initialize def initialize
@output_buffer = "original" @output_buffer = "original"
@virtual_path = nil @virtual_path = nil