Skip to content

Slots: Only answer a lookup that asks for slots first - #196

Open
mattboldt wants to merge 1 commit into
marcoroth:mainfrom
mattboldt:slots-resolver-first-format
Open

mattboldt wants to merge 1 commit into
marcoroth:mainfrom
mattboldt:slots-resolver-first-format

Conversation

@mattboldt

@mattboldt mattboldt commented Oct 24, 2026 •

Copy link
Copy Markdown

Hello! Another one from setting up ReActionView on my app (the first was marcoroth/herb#2778). Same disclosure as last time: I leaned on Claude for a lot of the digging here.


With config.slots = true, Slots::Resolver is prepended to the view paths and rebuilds every HTML template with the :slots format. It answers any lookup whose formats include :slots. Once the MIME type is registered, a lookup with default formats lists every registered format, :slots among them, so the prepended resolver wins and the render returns the values Hash where the caller expected markup.

# config.slots = true
lookup = ActionView::LookupContext.new(ActionController::Base.view_paths)
lookup.formats.first(3)  # => [:html, :text, :js]

lookup.find_template("shared/record_search_input", [], true, [:builder]).format
# => :slots

In our app this showed up as about 31 no implicit conversion of Hash into String errors from renders that aren't pinned to [:html]: ActionView::TestCase view tests, ViewComponent tests, and template.render inside simple_form inputs.

This makes the resolver return nothing unless :slots is the first requested format. A slots request still resolves as before, and everything else falls through to the resolvers Rails built.

Tested with test/slots/resolver_test.rb, which gets a case for a lookup that lists :slots after :html, and bundle exec rake test on this branch rebased onto current main (234 runs, 0 failures, 3 skips). We've been running it as a local patch on 0.6.0: the lookup above returns :html, a [:slots] lookup still returns :slots, and all 31 of those errors go away.

With `config.slots = true`, `Slots::Resolver` is prepended to the view
paths and answers any lookup whose formats include `:slots`. A lookup
with default formats lists every registered format, `:slots` among them,
so the prepended resolver wins and the render returns the values Hash
where the caller expected markup.

The resolver now returns nothing unless `:slots` is the first requested
format. A slots request still resolves as before, and everything else
falls through to the resolvers Rails built.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@mattboldt
mattboldt marked this pull request as ready for review October 24, 2026 18:33

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant