Skip to content

Commit 91d5736

Browse files
camertronjoelhawksley
authored andcommitted
Remove the global output buffer; compile on render_in (ViewComponent#1432)
* Remove the global output buffer; compile on render_in * Use rails main * Fix linting issues * Fix bad merge Co-authored-by: Joel Hawksley <[email protected]>
1 parent f9dfc08 commit 91d5736

20 files changed

+27
-306
lines changed

.github/workflows/ci.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ jobs:
2929
matrix:
3030
rails_version: ['5.2.6', '6.0.4.4', '6.1.4.4', '7.0.2.3', 'main']
3131
ruby_version: ['2.5', '2.6', '2.7', '3.0', '3.1']
32-
output_buffer: ['global_buffer', 'local_buffer']
3332
exclude:
3433
- rails_version: '5.2.6'
3534
ruby_version: '3.0'
@@ -66,7 +65,6 @@ jobs:
6665
RAISE_ON_WARNING: 1
6766
MEASURE_COVERAGE: true
6867
RAILS_VERSION: ${{ matrix.rails_version }}
69-
VIEW_COMPONENT_USE_GLOBAL_OUTPUT_BUFFER: ${{ matrix.output_buffer == 'global_buffer' && 'true' || 'false' }}
7068
- name: Upload coverage results
7169
uses: actions/upload-artifact@master
7270
if: always()

Gemfile

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,7 @@ gemspec
66
rails_version = (ENV["RAILS_VERSION"] || "~> 7.0.0").to_s
77

88
gem "capybara", "~> 3"
9-
10-
# https://github.com/rails/rails/pull/45614 broke our global output buffer
11-
# code, which we plan to remove anyways. Pinning to before it was merged
12-
# so CI will work.
13-
gem "rails", rails_version == "main" ? {git: "https://github.com/rails/rails", ref: "71c59c69f40cef908d0a97ef4b4c5496778559e5"} : rails_version
9+
gem "rails", rails_version == "main" ? {git: "https://github.com/rails/rails", ref: "main"} : rails_version
1410

1511
gem "rspec-rails", "~> 5"
1612

docs/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ title: Changelog
99

1010
## main
1111

12+
* Remove the experimental global output buffer feature.
13+
* Restore functionality that used to attempt to compile templates on each call to `#render_in`.
14+
* Un-pin `rails` `main` dependency.
15+
16+
*Cameron Dutro*
17+
1218
* Add blank space between "in" and "ViewComponent" in a deprecation warning.
1319

1420
*Vikram Dighe*

docs/known_issues.md

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,6 @@ title: Known issues
99

1010
ViewComponent [isn't compatible](https://github.com/github/view_component/issues/241) with `form_for` helpers by default.
1111

12-
### Using a Global Output Buffer
13-
14-
Since 2.52.0
15-
{: .label }
16-
17-
Experimental
18-
{: .label .label-yellow }
19-
20-
One possible solution to the form helpers problem is to use a single, global output buffer. For details, please refer to [this pull request](https://github.com/github/view_component/pull/1307).
21-
22-
The global output buffer behavior is opt-in. Prepend the `ViewComponent::GlobalOutputBuffer` module into individual component classes to use it.
23-
24-
For example:
25-
26-
```ruby
27-
class MyComponent < ViewComponent::Base
28-
prepend ViewComponent::GlobalOutputBuffer
29-
end
30-
```
31-
32-
It is also possible to enable the global output buffer globally by setting the `config.view_component.use_global_output_buffer` setting to `true` in your Rails config.
33-
3412
## Inconsistent controller rendering behavior between Rails versions
3513

3614
In versions of Rails < 6.1, rendering a ViewComponent from a controller doesn't include the layout.

lib/view_component.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ module ViewComponent
1111
autoload :CompileCache
1212
autoload :ComponentError
1313
autoload :Deprecation
14-
autoload :GlobalOutputBuffer
1514
autoload :Instrumentation
16-
autoload :OutputBufferStack
1715
autoload :Preview
1816
autoload :PreviewTemplateError
1917
autoload :TestHelpers

lib/view_component/base.rb

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,12 @@ def self._deprecated_generate_mattr_accessor(name)
8686
#
8787
# @return [String]
8888
def render_in(view_context, &block)
89+
self.class.compile(raise_errors: true)
90+
8991
@view_context = view_context
9092
self.__vc_original_view_context ||= view_context
9193

92-
@output_buffer = ActionView::OutputBuffer.new unless defined?(@global_buffer_in_use) && @global_buffer_in_use
94+
@output_buffer = ActionView::OutputBuffer.new
9395

9496
@lookup_context ||= view_context.lookup_context
9597

@@ -124,19 +126,14 @@ def render_in(view_context, &block)
124126
before_render
125127

126128
if render?
127-
perform_render
129+
render_template_for(@__vc_variant).to_s + _output_postamble
128130
else
129131
""
130132
end
131133
ensure
132134
@current_template = old_current_template
133135
end
134136

135-
# @private
136-
def perform_render
137-
render_template_for(@__vc_variant).to_s + _output_postamble
138-
end
139-
140137
# Subclass components that call `super` inside their template code will cause a
141138
# double render if they emit the result:
142139
#
@@ -152,17 +149,6 @@ def render_parent
152149
nil
153150
end
154151

155-
# @private
156-
# :nocov:
157-
def render_template_for(variant = nil)
158-
# Force compilation here so the compiler always redefines render_template_for.
159-
# This is mostly a safeguard to prevent infinite recursion.
160-
self.class.compile(raise_errors: true, force: true)
161-
# .compile replaces this method; call the new one
162-
render_template_for(variant)
163-
end
164-
# :nocov:
165-
166152
# EXPERIMENTAL: Optional content to be returned after the rendered template.
167153
#
168154
# @return [String]

lib/view_component/compile_cache.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,10 @@ def compiled?(klass)
2020

2121
def invalidate_class!(klass)
2222
cache.delete(klass)
23-
klass.compiler.reset_render_template_for
2423
end
2524

2625
def invalidate!
27-
cache.each { |klass| invalidate_class!(klass) }
26+
cache.clear
2827
end
2928
end
3029
end

lib/view_component/compiler.rb

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ def compile(raise_errors: false, force: false)
3434
component_class.superclass.compile(raise_errors: raise_errors) if should_compile_superclass?
3535

3636
with_lock do
37+
CompileCache.invalidate_class!(component_class)
38+
3739
subclass_instance_methods = component_class.instance_methods(false)
3840

3941
if subclass_instance_methods.include?(:with_content) && raise_errors
@@ -66,8 +68,8 @@ def compile(raise_errors: false, force: false)
6668
# as Ruby warns when redefining a method.
6769
method_name = call_method_name(template[:variant])
6870

69-
if component_class.instance_methods(false).include?(method_name.to_sym)
70-
component_class.send(:remove_method, method_name.to_sym)
71+
if component_class.instance_methods.include?(method_name.to_sym)
72+
component_class.send(:undef_method, method_name.to_sym)
7173
end
7274

7375
# rubocop:disable Style/EvalWithLocation
@@ -96,18 +98,14 @@ def with_lock(&block)
9698
end
9799
end
98100

99-
def reset_render_template_for
100-
if component_class.instance_methods(false).include?(:render_template_for)
101-
component_class.send(:remove_method, :render_template_for)
102-
end
103-
end
104-
105101
private
106102

107103
attr_reader :component_class
108104

109105
def define_render_template_for
110-
reset_render_template_for
106+
if component_class.instance_methods.include?(:render_template_for)
107+
component_class.send(:undef_method, :render_template_for)
108+
end
111109

112110
variant_elsifs = variants.compact.uniq.map do |variant|
113111
"elsif variant.to_sym == :#{variant}\n #{call_method_name(variant)}"

lib/view_component/engine.rb

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ class Engine < Rails::Engine # :nodoc:
2020
options.instrumentation_enabled = false if options.instrumentation_enabled.nil?
2121
options.preview_route ||= ViewComponent::Base.preview_route
2222
options.preview_controller ||= ViewComponent::Base.preview_controller
23-
options.use_global_output_buffer = false if options.use_global_output_buffer.nil?
2423

2524
if options.show_previews
2625
options.preview_paths << "#{Rails.root}/test/components/previews" if defined?(Rails.root) && Dir.exist?(
@@ -58,21 +57,6 @@ class Engine < Rails::Engine # :nodoc:
5857
end
5958
end
6059

61-
initializer "view_component.enable_global_output_buffer" do |app|
62-
ActiveSupport.on_load(:view_component) do
63-
env_use_gob = ENV.fetch("VIEW_COMPONENT_USE_GLOBAL_OUTPUT_BUFFER", "false") == "true"
64-
config_use_gob = app.config.view_component.use_global_output_buffer
65-
66-
if config_use_gob || env_use_gob
67-
# :nocov:
68-
app.config.view_component.use_global_output_buffer = true
69-
ViewComponent::Base.prepend(ViewComponent::GlobalOutputBuffer)
70-
ActionView::Base.prepend(ViewComponent::GlobalOutputBuffer::ActionViewMods)
71-
# :nocov:
72-
end
73-
end
74-
end
75-
7660
initializer "view_component.set_autoload_paths" do |app|
7761
options = app.config.view_component
7862

lib/view_component/global_output_buffer.rb

Lines changed: 0 additions & 100 deletions
This file was deleted.

0 commit comments

Comments
 (0)