Skip to content

A jbuilder partial! whose path is built at run time ("widgets/#{kind}") renders {} #360

Description

@eddygarcas

Probed with roundhouse 2026.9.18 (7fad14c0), Linux x86-64, CRuby 4.0.5, --target ruby (the spinel tree has the same view .rb).

A jbuilder partial! whose path is built when the template runs renders {}, with no diagnostic:

# app/views/widgets/_widget.json.jbuilder
json.id widget.id
json.name widget.name

# app/views/widgets/dynamic.json.jbuilder
kind = "widget"
json.partial!("widgets/#{kind}", widget: @widget)

Controller action: @widget = Widget.find(params[:id]) then render :dynamic; route get "widgets/:id/dynamic", to: "widgets#dynamic", defaults: { format: :json }; schema widgets(name string, size integer); ApplicationController < ActionController::Base.

request Rails 8.1.4 + jbuilder 2.15.1 --target ruby
GET /widgets/1/dynamic {"id":1,"name":"b"} {}

Emitted:

def self.dynamic_json(widget)
  io = String.new
  io << "{"
  io << ""
  io << ""
  io << "}"
  io
end

The real-world form picks one of a few partials by a record attribute or a param (json.partial! "things/#{thing.kind}", thing: thing).

Where it goes

src/lower/jbuilder_to_library/mod.rs, classify: the partial! arm needs string_literal(path_arg), and an interpolated path is an ExprNode::StringInterp, so the statement is Unknown. (The kind = … assignment is a separate gap: a template local is also Unknown; #359 keeps it.)

A path can't name a method at compile time, but the candidates are known: the _*.json.jbuilder partials under the path's fixed prefix (widgets/). One way is a case over the interpolated string with one when "widgets/widget" arm per candidate calling its <name>_json, and an else that raises the ActionView::MissingTemplate Rails would raise. That's a design call (and the arms' arities must agree), so I've left it as an issue. Short of that, a diagnostic for Unknown statements would have pointed at it.

Found while compiling a Rails API app with --target spinel.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions