diff --git a/lib/phlex/rails/sgml.rb b/lib/phlex/rails/sgml.rb index 6027345..715829b 100644 --- a/lib/phlex/rails/sgml.rb +++ b/lib/phlex/rails/sgml.rb @@ -10,11 +10,17 @@ def render_in(...) end module Overrides + class HelpersCalledBeforeRenderError < StandardError; end + def helpers - if defined?(ViewComponent::Base) && ViewComponent::Base === @_view_context - @_view_context.helpers + unless @_context && (view_context = @_context.view_context) + raise HelpersCalledBeforeRenderError.new("Do not use rails helpers until after the view has been rendered.") unless view_context + end + + if defined?(ViewComponent::Base) && ViewComponent::Base === view_context + view_context.helpers else - @_view_context + view_context end end @@ -22,18 +28,18 @@ def render(*args, **kwargs, &block) renderable = args[0] case renderable - when Phlex::SGML, Proc, Method, String - return super - when Class - return super if renderable < Phlex::SGML - when Enumerable - return super unless ActiveRecord::Relation === renderable - when nil - partial = kwargs.delete(:partial) + when Phlex::SGML, Proc, Method, String + return super + when Class + return super if renderable < Phlex::SGML + when Enumerable + return super unless ActiveRecord::Relation === renderable + when nil + partial = kwargs.delete(:partial) if partial # this is a hack to get around https://github.com/rails/rails/issues/51015 return raw( - @_view_context.render(partial, **kwargs) do |*yielded_args| + @_context.view_context.render(partial, **kwargs) do |*yielded_args| capture(*yielded_args, &block) end, ) @@ -43,7 +49,7 @@ def render(*args, **kwargs, &block) end output = if block - @_view_context.render(*args, **kwargs) do |*yielded_args| + @_context.view_context.render(*args, **kwargs) do |*yielded_args| if yielded_args.length == 1 && defined?(ViewComponent::Base) && ViewComponent::Base === yielded_args[0] capture(Phlex::Rails::Buffered.new(yielded_args[0], view: self), &block) else @@ -51,7 +57,7 @@ def render(*args, **kwargs, &block) end end else - @_view_context.render(*args, **kwargs) + @_context.view_context.render(*args, **kwargs) end raw(output) diff --git a/test/dummy/app/controllers/helpers_controller.rb b/test/dummy/app/controllers/helpers_controller.rb index 8e9d2db..4eb873b 100644 --- a/test/dummy/app/controllers/helpers_controller.rb +++ b/test/dummy/app/controllers/helpers_controller.rb @@ -3,6 +3,10 @@ class HelpersController < ApplicationController layout false + def helper_in_initializer + render Helpers::HelperInInitializer.new + end + def form_with render Helpers::FormWithView.new end diff --git a/test/dummy/app/views/helpers/helper_in_initializer.rb b/test/dummy/app/views/helpers/helper_in_initializer.rb new file mode 100644 index 0000000..4ecf9f9 --- /dev/null +++ b/test/dummy/app/views/helpers/helper_in_initializer.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class Helpers::HelperInInitializer < ApplicationView + include Phlex::Rails::Helpers::Routes + + def initialize + helpers_helper_in_initializer_path + end +end diff --git a/test/dummy/config/routes.rb b/test/dummy/config/routes.rb index b4b089d..c309a65 100644 --- a/test/dummy/config/routes.rb +++ b/test/dummy/config/routes.rb @@ -13,6 +13,7 @@ get "/layout/with_erb_view", to: "layout#with_erb_view" get "/layout/with_phlex_view", to: "layout#with_phlex_view" + get "/helpers/helper_in_initializer", to: "helpers#helper_in_initializer" get "/helpers/form_with", to: "helpers#form_with" get "/helpers/tag", to: "helpers#tag" get "/helpers/missing_helper", to: "helpers#missing_helper" diff --git a/test/phlex/helpers_test.rb b/test/phlex/helpers_test.rb index 918c27b..895a638 100644 --- a/test/phlex/helpers_test.rb +++ b/test/phlex/helpers_test.rb @@ -14,6 +14,14 @@ class HelpersTest < ActionDispatch::IntegrationTest end end + test "helper in initializer" do + error = assert_raises(Phlex::Rails::SGML::Overrides::HelpersCalledBeforeRenderError) do + get "/helpers/helper_in_initializer" + end + + assert_equal "Do not use rails helpers until after the view has been rendered.", error.message + end + test "form with" do get "/helpers/form_with"