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

Merge pull request #36388 from joelhawksley/actionview-component

Introduce ActionView::Component
This commit is contained in:
Aaron Patterson 2019-06-13 09:37:49 -07:00 committed by GitHub
commit 3683a828dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 1 deletions

View file

@ -1,3 +1,7 @@
* `RenderingHelper` supports rendering objects that `respond_to?` `:render_in`
*Joel Hawksley*, *Natasha Umer*, *Aaron Patterson*, *Shawn Allen*, *Emily Plummer*, *Diana Mounter*, *John Hawthorn*, *Nathan Herald*, *Zaid Zawaideh*, *Zach Ahn*
* Fix `select_tag` so that it doesn't change `options` when `include_blank` is present. * Fix `select_tag` so that it doesn't change `options` when `include_blank` is present.
*Younes SERRAJ* *Younes SERRAJ*

View file

@ -35,7 +35,11 @@ module ActionView
end end
end end
else else
view_renderer.render_partial(self, partial: options, locals: locals, &block) if options.respond_to?(:render_in)
options.render_in(self, &block)
else
view_renderer.render_partial(self, partial: options, locals: locals, &block)
end
end end
end end

View file

@ -0,0 +1,46 @@
# frozen_string_literal: true
class TestComponent < ActionView::Base
include ActiveModel::Validations
validates :content, :title, presence: true
delegate :render, to: :view_context
def initialize(title:)
@title = title
end
# Entrypoint for rendering. Called by ActionView::RenderingHelper#render.
#
# Returns ActionView::OutputBuffer.
def render_in(view_context, &block)
self.class.compile
@view_context = view_context
@content = view_context.capture(&block) if block_given?
validate!
rendered_template
end
def self.template
<<~'erb'
<span title="<%= title %>"><%= content %> (<%= render(plain: "Inline render") %>)</span>
erb
end
def self.compile
@compiled ||= nil
return if @compiled
class_eval(
"def rendered_template; @output_buffer = ActionView::OutputBuffer.new; " +
ActionView::Template::Handlers::ERB.erb_implementation.new(template, trim: true).src +
"; end"
)
@compiled = true
end
private
attr_reader :content, :title, :view_context
end

View file

@ -2,6 +2,8 @@
require "abstract_unit" require "abstract_unit"
require "controller/fake_models" require "controller/fake_models"
require "test_component"
require "active_model/validations"
class TestController < ActionController::Base class TestController < ActionController::Base
end end
@ -670,6 +672,21 @@ module RenderTestCases
def test_render_throws_exception_when_no_extensions_passed_to_register_template_handler_function_call def test_render_throws_exception_when_no_extensions_passed_to_register_template_handler_function_call
assert_raises(ArgumentError) { ActionView::Template.register_template_handler CustomHandler } assert_raises(ArgumentError) { ActionView::Template.register_template_handler CustomHandler }
end end
def test_render_component
assert_equal(
%(<span title="my title">Hello, World! (Inline render)</span>),
@view.render(TestComponent.new(title: "my title")) { "Hello, World!" }.strip
)
end
def test_render_component_with_validation_error
error = assert_raises(ActiveModel::ValidationError) do
@view.render(TestComponent.new(title: "my title")).strip
end
assert_match "Content can't be blank", error.message
end
end end
class CachedViewRenderTest < ActiveSupport::TestCase class CachedViewRenderTest < ActiveSupport::TestCase