Bug Report Checklist
Description
ruby-nextgen puts nested resources in their own class (/stables/{stable}/ponies/{pony} → Api::Stables::Ponies), but the client offers no way to reach them. RubyNextgenClientCodegen#postProcessSupportingFileData computes a resources list for each namespace in rbNamespaces, but client.mustache only renders the namespace accessors, and the namespace class has no accessors either. The only way to call a nested operation is Petstore::Api::Stables::Ponies.new(client.connection).
If a namespace has only nested paths (no /stables or /stables/{stable} operation), it gets worse: Zeitwerk makes Api::Stables an implicit module from the api/stables/ directory, and the generated client.stables accessor calls Stables.new on it, which raises NoMethodError: undefined method 'new' for module Petstore::Api::Stables.
openapi-generator version
master, 7.26.0-SNAPSHOT, 05b61f34d7fb0199330e1d6c57e6159f72427837
OpenAPI declaration file content or url
openapi: 3.0.3
info:
title: nested
version: 1.0.0
paths:
/stables:
get:
operationId: listStables
responses:
'200':
description: OK
/stables/{stable}:
get:
operationId: getStable
parameters:
- name: stable
in: path
required: true
schema:
type: string
responses:
'200':
description: OK
/stables/{stable}/ponies/{pony}:
get:
operationId: getPony
parameters:
- name: stable
in: path
required: true
schema:
type: string
- name: pony
in: path
required: true
schema:
type: string
responses:
'200':
description: OK
Generation Details
java -jar openapi-generator-cli.jar generate -g ruby-nextgen -i spec.yaml -o out \
--additional-properties=gemName=petstore,moduleName=Petstore
This generates api/stables.rb (Stables#get, Stables#list) and api/stables/ponies.rb (Stables::Ponies#get). Generated lib/petstore/client.rb:
module Petstore
class Client
attr_reader :configuration, :connection
def initialize(base_url: nil, **options, &block)
@configuration = Configuration.new(base_url: base_url, **options, &block)
@connection = Connection.new(@configuration)
end
def stables
@stables ||= Petstore::Api::Stables.new(@connection)
end
end
end
Steps to reproduce
$LOAD_PATH.unshift 'out/lib'
require 'petstore'
client = Petstore::Client.new(base_url: 'http://localhost')
client.stables.ponies.get(stable: 'a', pony: 'b')
Actual (ruby 3.3):
undefined method `ponies' for an instance of Petstore::Api::Stables (NoMethodError)
Expected: client.stables.ponies returns a Petstore::Api::Stables::Ponies, matching the client.<resource>.<action> shape in the generated README.
Related issues/PRs
None found.
Suggest a fix
Render the resources that are already computed, as the crystal generator does in its client.mustache (a {{#resources}} accessor on each namespace class). The api templates are written before postProcessSupportingFileData runs, so the namespace-to-resources map has to be built earlier (e.g. from resourceSegments and the paths in preprocessOpenAPI) and passed to api.mustache for the namespace class:
def ponies
@ponies ||= Stables::Ponies.new(@connection)
end
For a namespace with only nested paths, the generator must still emit a namespace class (without operations) so that client.stables has something to instantiate.
Generated with Claude Code
Bug Report Checklist
Description
ruby-nextgenputs nested resources in their own class (/stables/{stable}/ponies/{pony}→Api::Stables::Ponies), but the client offers no way to reach them.RubyNextgenClientCodegen#postProcessSupportingFileDatacomputes aresourceslist for each namespace inrbNamespaces, butclient.mustacheonly renders the namespace accessors, and the namespace class has no accessors either. The only way to call a nested operation isPetstore::Api::Stables::Ponies.new(client.connection).If a namespace has only nested paths (no
/stablesor/stables/{stable}operation), it gets worse: Zeitwerk makesApi::Stablesan implicit module from theapi/stables/directory, and the generatedclient.stablesaccessor callsStables.newon it, which raisesNoMethodError: undefined method 'new' for module Petstore::Api::Stables.openapi-generator version
master, 7.26.0-SNAPSHOT,
05b61f34d7fb0199330e1d6c57e6159f72427837OpenAPI declaration file content or url
Generation Details
This generates
api/stables.rb(Stables#get,Stables#list) andapi/stables/ponies.rb(Stables::Ponies#get). Generatedlib/petstore/client.rb:Steps to reproduce
Actual (ruby 3.3):
Expected:
client.stables.poniesreturns aPetstore::Api::Stables::Ponies, matching theclient.<resource>.<action>shape in the generated README.Related issues/PRs
None found.
Suggest a fix
Render the
resourcesthat are already computed, as thecrystalgenerator does in itsclient.mustache(a{{#resources}}accessor on each namespace class). The api templates are written beforepostProcessSupportingFileDataruns, so the namespace-to-resources map has to be built earlier (e.g. fromresourceSegmentsand the paths inpreprocessOpenAPI) and passed toapi.mustachefor the namespace class:For a namespace with only nested paths, the generator must still emit a namespace class (without operations) so that
client.stableshas something to instantiate.Generated with Claude Code