Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ Running `wheels generate` with no arguments prints the list of supported types a

## Attribute syntax

Most generators accept a trailing list of `name:type` property pairs after the resource name. The parser also recognises a few `--belongsTo=`, `--hasMany=`, and `--hasOne=` flags for associations. Type names are normalised to Wheels migration column types — unknown types fall back to `string`.
Property-aware generators — `model`, `scaffold`, `api-resource`, and `property` — accept a trailing list of `name:type` property pairs after the resource name. They also recognise `--belongsTo=`, `--hasMany=`, and `--hasOne=` flags for associations. Type names are normalised to Wheels migration column types — unknown types fall back to `string`.

The other generators (`controller`, `view`, `migration`, `route`, `test`, `helper`, `snippets`, `admin`) take their own positional arguments — see the per-subcommand Synopsis sections below for what each accepts.
Comment on lines +50 to +52
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 The new lead paragraph overstates what three of the four "property-aware" generators accept, contradicting the per-subcommand Synopsis sections later on the same page. (1) generate property only takes a single property:type and ignores all association flags — generateProperty in cli/lucli/Module.cfc:2692-2740 reads only args[1]/args[2] and never calls parseGeneratorArgs. (2) generate scaffold and generate api-resource silently drop --hasOne=; the call sites at Module.cfc:2592-2598 and 2768-2773 forward only belongsTo and hasMany, and Scaffold.cfc:25-33/362-369 don't even define a hasOne parameter. Suggest splitting property out (single name:type, no flags) and noting that only model honors --hasOne= while scaffold/api-resource accept --belongsTo= and --hasMany= only.

Extended reasoning...

What the bug is

The PR's new lead under ## Attribute syntax reads:

Property-aware generators — model, scaffold, api-resource, and property — accept a trailing list of name:type property pairs after the resource name. They also recognise --belongsTo=, --hasMany=, and --hasOne= flags for associations.

This is a single, blanket claim about all four generators. It is wrong in two distinct ways, and it contradicts the Synopsis blocks lower in the same file.

Why it's wrong — property

generateProperty in cli/lucli/Module.cfc:2692-2740 only reads args[1] (model name) and args[2] (a single property:type), splits the second on :, and uses parts[1]/parts[2]. There is no loop over additional positional args, no parseGeneratorArgs() call, and no --belongsTo/--hasMany/--hasOne recognition. parseGeneratorArgs is only called from generateModel (2437), generateScaffold (2589), and generateApiResource (2765). The doc's own Synopsis confirms this — wheels generate property <ModelName> <property:type> (singular, no flags) — and the example passes exactly one property.

Why it's wrong — scaffold and api-resource on --hasOne

parseGeneratorArgs (Module.cfc:4798) does collect a hasOne array, but the scaffold call site at Module.cfc:2592-2598 and the api-resource call site at Module.cfc:2768-2773 forward only belongsTo and hasMany to the service. The receiving signatures confirm this: services/Scaffold.cfc:25-33 (generateScaffold(name, properties, belongsTo, hasMany, api, tests, force)) and 362-369 (generateApiResource(name, properties, belongsTo, hasMany, tests, force)) have no hasOne parameter. Only generateModel (Module.cfc:2447-2453) wires hasOne through. The per-subcommand Synopsis sections for scaffold and api-resource correctly omit --hasOne=, so the new lead also contradicts the rest of the page.

Impact

The PR's stated goal is to remove ambiguity by naming exactly which generators accept the attribute syntax. Instead it introduces a fresh, easily-checkable inaccuracy. A reader following the new lead and running:

wheels generate property User email:string phone:string --belongsTo=org

…gets a single email:string migration with phone:string and --belongsTo=org silently discarded. Likewise:

wheels generate scaffold Post --hasOne=profile

…generates the resource with no hasOne association — no error, no warning. That is the same kind of confusion the PR sets out to fix.

Step-by-step proof for generate property

  1. User reads new lead: "property… accept[s] a trailing list of name:type property pairs… also recognise --belongsTo=, --hasMany=, --hasOne=."
  2. User runs wheels generate property User a:string b:string --belongsTo=org.
  3. Module.cfc:2692 generateProperty enters; reads args[1] = "User" and args[2] = "a:string". Splits a:string on :parts[1]=a, parts[2]=string.
  4. No loop over args[3..]; b:string and --belongsTo=org are never inspected.
  5. Generator emits a single add-column migration for column a and prints success. The user's other inputs are gone.

Step-by-step proof for scaffold --hasOne

  1. User runs wheels generate scaffold Post --hasOne=profile.
  2. Module.cfc:2589 calls parseGeneratorArgs(args). Result includes parsed.hasOne = ["profile"].
  3. Module.cfc:2592-2598 invokes scaffold.generateScaffold(name="Post", properties=…, belongsTo=…, hasMany=…, …). parsed.hasOne is never passed.
  4. Scaffold.cfc:25 generateScaffold has no hasOne parameter to receive it. The value is gone.
  5. The generated Post.cfc contains no hasOne(name="profile") line; no warning is printed.

Suggested fix

Split the lead into something like:

model, scaffold, and api-resource accept a trailing list of name:type property pairs after the resource name. They also recognise --belongsTo= and --hasMany= flags for associations; model additionally recognises --hasOne=. generate property takes a single <ModelName> <property:type> and does not accept association flags.

That keeps the goal of the PR (naming which generators take the attribute syntax) while matching what the implementation actually does and the Synopsis sections below.


| You write | Column type | Notes |
|---|---|---|
Expand Down
Loading