Skip to content

Improve generators attributes #5987

Open
@ShPakvel

Description

@ShPakvel

Topic

CLI attributes format for mix phx.gen.* tasks.

Current format all:values:separated:with:only:colons

It is very simple but not flexible and robust.
Which make underneath code more coupled and fragile with every enhancement.
Hence leading to clashes, like in examples bellow.


Issue(s)

Core issue is that different parts of an attribute info are mixed and coupled in very simple format.
There is no clear boundaries to extract specifics of types and general options.

Examples:

This issue describes already existing bug with compound :array:enum:value type. Which should be allowed according to the task description.

Another issue with enum values clash to options.
Let's say we need value redact or unique. Like stages:enum:publish:review:redact.
Right now intended enum value redact will be treated as option redact: true for schema field stages.

Similarly, if we want to enhance options of attribute, they can clash with other parts.
E.g. my initial idea for small feature.
I wanted to add field option required (maybe with alias *). And use it to generate proper representation across layers:

  • In migration, add null: false constraint to related column.
  • In schema, add only such marked fields into list of validate_required([...]) logic.
  • In html form, add required attribute to related input.
    This easily can clash for instance with enum value as previous already existing clashes described.

Another hiccup I met when tried to follow phoenix guide.
When decimal column in migration was manually provided with options precision: 15, scale: 6 before migrating generated code.
It led to failing tests with previously generated default values in fixtures in wrong values/format.
Which could be nicely resolved with options for precision and scale.

With references at the beginning I was surprised how little we generate for general behavior, and need to update manually after.
Digging a bit of code history I encountered issue related to possible context differences.

  • One way to resolve it could be replacing field_name:references:table with field_name:references:Context.Schema. We generate in scope of phx.gen.schema after all. Having specified referenced schema we could infer necessary info from its reflection. For instance, needed first of all __schema__(:source), as well as correct referenced column type.

Solution Proposal

Main goal.
Keep attribute CLI format simple for general cases, while improving flexibility for type and options enhancements for specific cases.

So main change we want to do is for clear separation of types from options, and among options.

My suggestion is

Attribute cli format in details.
There are still 3 main parts of attribute format: name, type, options. They divided by ":".

  • name is always present.
  • type is one of the valid values. Default to string. Array presented as [array,inner_type].
  • options is a list separated by ":". An option mimics its counterpart from mentioned functions. Some options can be mandatory, see enum case for example. Some options are for enhanced code generation. Option can use characters , [, ] to format details.

With this we can improve format parsing.
Make it more independent per type and per option.
Thus simpler logic with less clashes and hence bugs.

I will attach PR with solution soon.

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

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions