Skip to content

Commit

Permalink
Fix rendering Action Text HTML in new threads
Browse files Browse the repository at this point in the history
Because `ActionText::Content.renderer` is implemented as a
`thread_cattr_accessor`, any default value set in the main thread will
be inaccessible from other threads.  Therefore, use a `cattr_accessor`
to store the default renderer, and fall back to it when `renderer` has
not been set by e.g. `with_renderer`.

Fixes #40757.
  • Loading branch information
jonathanhefner committed Dec 7, 2020
1 parent 9b60089 commit ef61c9c
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 2 deletions.
2 changes: 1 addition & 1 deletion actiontext/lib/action_text/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def to_trix_content_attachment_partial_path

initializer "action_text.renderer" do
ActiveSupport.on_load(:action_text_content) do
self.renderer = Class.new(ActionController::Base).renderer
self.default_renderer = Class.new(ActionController::Base).renderer
end

%i[action_controller_base action_mailer].each do |abstract_controller|
Expand Down
3 changes: 2 additions & 1 deletion actiontext/lib/action_text/rendering.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module Rendering #:nodoc:
extend ActiveSupport::Concern

included do
cattr_accessor :default_renderer, instance_accessor: false
thread_cattr_accessor :renderer, instance_accessor: false
delegate :render, to: :class
end
Expand All @@ -22,7 +23,7 @@ def with_renderer(renderer)
end

def render(*args, &block)
renderer.render_to_string(*args, &block)
(renderer || default_renderer).render_to_string(*args, &block)
end
end
end
Expand Down
9 changes: 9 additions & 0 deletions actiontext/test/unit/content_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,15 @@ class ActionText::ContentTest < ActiveSupport::TestCase
assert_not defined?(::ApplicationController)
end

test "renders with layout when in a new thread" do
html = "<h1>Hello world</h1>"
rendered = nil
Thread.new { rendered = content_from_html(html).to_rendered_html_with_layout }.join

assert_includes rendered, html
assert_match %r/\A#{Regexp.escape '<div class="trix-content">'}/, rendered
end

private
def content_from_html(html)
ActionText::Content.new(html).tap do |content|
Expand Down

0 comments on commit ef61c9c

Please sign in to comment.