Skip to content

Commit 4117583

Browse files
committed
Document rendering :renderable and #render_in
Provide examples for rendering objects that respond to `render_in`. Also highlight that the object can also define a `#format` method to control how the rendered String should be treated. Add test coverage for both Action View's and Action Pack's support for `render` with `:renderable` options.
1 parent b294a25 commit 4117583

File tree

5 files changed

+50
-7
lines changed

5 files changed

+50
-7
lines changed

actionpack/lib/action_controller/metal/rendering.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,22 @@ def inherited(klass)
3939
# If the first argument responds to +render_in+, the template will be
4040
# rendered by calling +render_in+ with the current view context.
4141
#
42+
# class Greeting
43+
# def render_in(view_context)
44+
# view_context.render html: "<h1>Hello, World</h1>"
45+
# end
46+
#
47+
# def format
48+
# :html
49+
# end
50+
# end
51+
#
52+
# render(Greeting.new)
53+
# # => "<h1>Hello, World</h1>"
54+
#
55+
# render(renderable: Greeting.new)
56+
# # => "<h1>Hello, World</h1>"
57+
#
4258
# ==== \Rendering Mode
4359
#
4460
# [+:partial+]
@@ -92,6 +108,14 @@ def inherited(klass)
92108
# render json: { hello: "world" }
93109
# # => renders "{\"hello\":\"world\"}"
94110
#
111+
# [+:renderable+]
112+
# Renders the provided object by calling +render_in+ with the current view
113+
# context. The response format is determined by calling +format+ on the
114+
# renderable if it responds to +format+, falling back to +text/html+ by default.
115+
#
116+
# render renderable: Greeting.new
117+
# # => renders "<h1>Hello, World</h1>"
118+
#
95119
# By default, when a rendering mode is specified, no layout template is
96120
# rendered.
97121
#

actionpack/test/controller/renderer_test.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ class RendererTest < ActiveSupport::TestCase
7373
%(Hello, World!),
7474
renderer.render(TestRenderable.new)
7575
)
76+
assert_equal(
77+
%(Hello, World!),
78+
renderer.render(renderable: TestRenderable.new)
79+
)
7680
end
7781

7882
test "rendering with custom env" do

actionview/lib/action_view/template/renderable.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def render(context, *args)
1717
end
1818

1919
def format
20-
@renderable.format
20+
@renderable.try(:format)
2121
end
2222
end
2323
end

actionview/test/template/render_test.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,11 @@ def test_render_renderable_object
375375
assert_equal "NilClass", @view.render(partial: "test/klass", object: nil)
376376
end
377377

378+
def test_render_renderable_render_in
379+
assert_equal "Hello, World!", @view.render(TestRenderable.new)
380+
assert_equal "Hello, World!", @view.render(renderable: TestRenderable.new)
381+
end
382+
378383
def test_render_object_different_name
379384
assert_equal "Hello: t.lo", @view.render(partial: "test/template_not_named_customer", object: Customer.new("t.lo"), as: "customer").chomp
380385
end

guides/source/layouts_and_rendering.md

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -283,18 +283,28 @@ TIP: `send_file` is often a faster and better option if a layout isn't required.
283283

284284
#### Rendering Objects
285285

286-
Rails can render objects responding to `:render_in`.
286+
Rails can render objects responding to `#render_in`. The format can be controlled by defining `#format` on the object.
287287

288288
```ruby
289-
render MyRenderable.new
290-
```
289+
class Greeting
290+
def render_in(view_context)
291+
view_context.render html: "Hello, World"
292+
end
293+
294+
def format
295+
:html
296+
end
297+
end
291298

292-
This calls `render_in` on the provided object with the current view context.
299+
render Greeting.new
300+
# => "Hello World"
301+
```
293302

294-
You can also provide the object by using the `:renderable` option to `render`:
303+
This calls `render_in` on the provided object with the current view context. You can also provide the object by using the `:renderable` option to `render`:
295304

296305
```ruby
297-
render renderable: MyRenderable.new
306+
render renderable: Greeting.new
307+
# => "Hello World"
298308
```
299309

300310
#### Options for `render`

0 commit comments

Comments
 (0)