diff --git a/actionpack/test/controller/new_base/render_layout_test.rb b/actionpack/test/controller/new_base/render_layout_test.rb index 806c6206dc..2e6f7efd3a 100644 --- a/actionpack/test/controller/new_base/render_layout_test.rb +++ b/actionpack/test/controller/new_base/render_layout_test.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require "abstract_unit" +require "test_renderable" module ControllerLayouts class ImplicitController < ::ApplicationController @@ -19,6 +20,10 @@ module ControllerLayouts render template: "basic", layout: "override" end + def override_renderable + render TestRenderable.new, layout: "override" + end + def layout_false render layout: false end @@ -36,6 +41,10 @@ module ControllerLayouts def index render template: "basic" end + + def renderable + render TestRenderable.new + end end class RenderLayoutTest < Rack::TestCase @@ -53,6 +62,20 @@ module ControllerLayouts assert_status 200 end + test "rendering a renderable object, using the implicit layout" do + get "/controller_layouts/implicit_name/renderable" + + assert_body "Implicit Hello, World! Layout" + assert_status 200 + end + + test "rendering a renderable object, using the override layout" do + get "/controller_layouts/implicit/override_renderable" + + assert_body "Override! Hello, World!" + assert_status 200 + end + test "overriding an implicit layout with render :layout option" do get "/controller_layouts/implicit/override" assert_body "Override! Hello world!" diff --git a/actionpack/test/controller/renderer_test.rb b/actionpack/test/controller/renderer_test.rb index 4d45c082d7..75a2767c0d 100644 --- a/actionpack/test/controller/renderer_test.rb +++ b/actionpack/test/controller/renderer_test.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require "abstract_unit" -require "test_component" +require "test_renderable" class RendererTest < ActiveSupport::TestCase test "action controller base has a renderer" do @@ -66,12 +66,12 @@ class RendererTest < ActiveSupport::TestCase assert_equal "The secret is foo\n", content end - def test_render_component + test "render a renderable object" do renderer = ApplicationController.renderer assert_equal( %(Hello, World!), - renderer.render(TestComponent.new) + renderer.render(TestRenderable.new) ) end diff --git a/actionpack/test/lib/test_component.rb b/actionpack/test/lib/test_renderable.rb similarity index 85% rename from actionpack/test/lib/test_component.rb rename to actionpack/test/lib/test_renderable.rb index 1207c35c0f..46e2f8983c 100644 --- a/actionpack/test/lib/test_component.rb +++ b/actionpack/test/lib/test_renderable.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class TestComponent +class TestRenderable def render_in(_view_context) "Hello, World!" end diff --git a/actionview/lib/action_view/renderer/renderer.rb b/actionview/lib/action_view/renderer/renderer.rb index b9278adafd..e7f4296229 100644 --- a/actionview/lib/action_view/renderer/renderer.rb +++ b/actionview/lib/action_view/renderer/renderer.rb @@ -25,9 +25,6 @@ module ActionView def render_to_object(context, options) # :nodoc: if options.key?(:partial) render_partial_to_object(context, options) - elsif options.key?(:object) - object = options[:object] - AbstractRenderer::RenderedTemplate.new(object.render_in(context), object) else render_template_to_object(context, options) end diff --git a/actionview/lib/action_view/renderer/template_renderer.rb b/actionview/lib/action_view/renderer/template_renderer.rb index f20e786b61..ee159c08aa 100644 --- a/actionview/lib/action_view/renderer/template_renderer.rb +++ b/actionview/lib/action_view/renderer/template_renderer.rb @@ -37,6 +37,8 @@ module ActionView @lookup_context.formats.first end Template::Inline.new(options[:inline], "inline template", handler, locals: keys, format: format) + elsif options.key?(:renderable) + Template::Renderable.new(options[:renderable]) elsif options.key?(:template) if options[:template].respond_to?(:render) options[:template] diff --git a/actionview/lib/action_view/rendering.rb b/actionview/lib/action_view/rendering.rb index 1ffd59599b..cecaee15d0 100644 --- a/actionview/lib/action_view/rendering.rb +++ b/actionview/lib/action_view/rendering.rb @@ -145,7 +145,7 @@ module ActionView if action.respond_to?(:permitted?) && action.permitted? options = action elsif action.respond_to?(:render_in) - options[:object] = action + options[:renderable] = action else options[:partial] = action end diff --git a/actionview/lib/action_view/template.rb b/actionview/lib/action_view/template.rb index 035aee2aa6..c45f9187f4 100644 --- a/actionview/lib/action_view/template.rb +++ b/actionview/lib/action_view/template.rb @@ -111,6 +111,7 @@ module ActionView eager_autoload do autoload :Error autoload :RawFile + autoload :Renderable autoload :Handlers autoload :HTML autoload :Inline diff --git a/actionview/lib/action_view/template/renderable.rb b/actionview/lib/action_view/template/renderable.rb new file mode 100644 index 0000000000..09e0fddd85 --- /dev/null +++ b/actionview/lib/action_view/template/renderable.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module ActionView + # = Action View Renderable Template for objects that respond to #render_in + class Template + class Renderable # :nodoc: + def initialize(renderable) + @renderable = renderable + end + + def identifier + @renderable.class.name + end + + def render(context, *args) + @renderable.render_in(context) + end + + def format + @renderable.format + end + end + end +end diff --git a/actionview/test/fixtures/.DS_Store b/actionview/test/fixtures/.DS_Store new file mode 100644 index 0000000000..d8a77e7468 Binary files /dev/null and b/actionview/test/fixtures/.DS_Store differ diff --git a/actionview/test/lib/test_component.rb b/actionview/test/lib/test_renderable.rb similarity index 81% rename from actionview/test/lib/test_component.rb rename to actionview/test/lib/test_renderable.rb index f00b8b2d3a..c2b7411e14 100644 --- a/actionview/test/lib/test_component.rb +++ b/actionview/test/lib/test_renderable.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class TestComponent +class TestRenderable def render_in(_view_context) "Hello, World!" end diff --git a/actionview/test/template/render_test.rb b/actionview/test/template/render_test.rb index 445cb9a64a..395891be98 100644 --- a/actionview/test/template/render_test.rb +++ b/actionview/test/template/render_test.rb @@ -2,7 +2,7 @@ require "abstract_unit" require "controller/fake_models" -require "test_component" +require "test_renderable" require "active_model/validations" class TestController < ActionController::Base @@ -331,7 +331,7 @@ module RenderTestCases assert_match(/`undefined' for #/, e.message) end - def test_render_object + def test_render_renderable_object assert_equal "Hello: david", @view.render(partial: "test/customer", object: Customer.new("david")) assert_equal "FalseClass", @view.render(partial: "test/klass", object: false) assert_equal "NilClass", @view.render(partial: "test/klass", object: nil) @@ -697,10 +697,10 @@ module RenderTestCases assert_raises(ArgumentError) { ActionView::Template.register_template_handler CustomHandler } end - def test_render_component + def test_render_object assert_equal( %(Hello, World!), - @view.render(TestComponent.new) + @view.render(TestRenderable.new) ) end end diff --git a/guides/source/layouts_and_rendering.md b/guides/source/layouts_and_rendering.md index 62e8b9a73a..c36b681fdf 100644 --- a/guides/source/layouts_and_rendering.md +++ b/guides/source/layouts_and_rendering.md @@ -282,7 +282,7 @@ TIP: `send_file` is often a faster and better option if a layout isn't required. Rails can render objects responding to `:render_in`. ```ruby -render MyComponent.new +render MyRenderable.new ``` This calls `render_in` on the provided object with the current view context.