Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start passing in an option to ActiveRecordColumns compiler for how to generate column types #1888

Merged
merged 14 commits into from
Jun 4, 2024

Conversation

paracycle
Copy link
Member

Motivation

One of the most painful parts of Tapioca has historically been the types generated for Active Record columns.

Strictly speaking, an AR model will always have all of its column attributes as nilable, since one can always do Model.new and validations actually behave on this fact being true. However, treating every column attribute as nilable is painful in user code and requires a bunch of T.musts to be added depending on user intent. For that reason, most developers actually prefer to have the database nullability define the nilable status of a column, since most of the time models are dehydrated from database rows.

As an in-between measure, it is also possible to define all column attributes to be T.untyped so that one can defer dealing with what the exact types should be to a later date (which is what we do at Shopify in our Core monolith - except for a few models that include a special module called StrongTypeGeneration).

Until now, there was no way to choose between these options, and this PR is aiming to add this as a compiler option that can be different for each codebase.

/cc @KaanOzkan

Implementation

The implementation is backwards compatible with existing DSL compiler implementations and only adds an extra optional parameter to the constructor of each DSL compiler named options. Each compiler is responsible for declaring what options it supports and with which values.

This configuration is injected from the CLI/config layer through a hash valued CLI option compiler_options, which takes in compiler names as keys and config options for the compiler as values.

ActiveRecordColumns compiler declares a single option named types which can have the values:

  • untyped: which generates all column attributes as T.untyped,
  • persisted: which generates all column attributes as nilable only if the database column is marked nullable,
  • nilable: which generates all column attributes as nilable (as they should be)

The default behaviour of this option is set as persisted so that the behaviour of this compiler does not change drastically.

Tests

Updated existing compiler tests and added a CLI test to ensure that options are passed correctly to ActiveRecordColumns compiler.

@paracycle paracycle added the enhancement New feature or request label May 1, 2024
paracycle and others added 12 commits May 2, 2024 17:31
Co-authored-by: Alexandre Terrasa <583144+Morriar@users.noreply.github.com>
This is either 'untyped', 'nilable', or 'persisted', with the old behaviour being approximated by 'persisted'

Co-authored-by: Alexandre Terrasa <583144+Morriar@users.noreply.github.com>
Co-authored-by: Alexandre Terrasa <583144+Morriar@users.noreply.github.com>
All the tests that were testing existence of StrongTypeGeneration but with the model not extending it are now actually testing the "untyped" option for the `column_types` compiler option to AR columns compiler.

Co-authored-by: Alexandre Terrasa <583144+Morriar@users.noreply.github.com>
Co-authored-by: Alexandre Terrasa <583144+Morriar@users.noreply.github.com>
Co-authored-by: Alexandre Terrasa <583144+Morriar@users.noreply.github.com>
Co-authored-by: Alexandre Terrasa <583144+Morriar@users.noreply.github.com>
Co-authored-by: Alexandre Terrasa <583144+Morriar@users.noreply.github.com>
Co-authored-by: Alexandre Terrasa <583144+Morriar@users.noreply.github.com>
Co-authored-by: Alexandre Terrasa <583144+Morriar@users.noreply.github.com>
Co-authored-by: Alexandre Terrasa <583144+Morriar@users.noreply.github.com>
Co-authored-by: Alexandre Terrasa <583144+Morriar@users.noreply.github.com>
Since this option cannot be supplied properly on the command line, we should hide it as a command line option, but support it in the configuration file. We also error out if the option as supplied does not have proper hashes as values.
Instead of erroring out when the compiler options are not supplied as hashes, we could try to first parse them as YAML (if they are supplied as strings) and only then error if any of the compiler options isn't a hash.

This allows users to supply compiler options as strings in the `tapioca` CLI as:
```
dsl Post --compiler-options='ActiveRecordColumns:{types: untyped}'
```
which is more user-friendly than not being able to pass these options on the command line.
@paracycle paracycle marked this pull request as ready for review June 4, 2024 14:09
@paracycle paracycle requested a review from a team as a code owner June 4, 2024 14:09
Copy link
Contributor

@KaanOzkan KaanOzkan left a comment

Choose a reason for hiding this comment

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

I think this is worth documenting in ActiveRecordColumns compiler and the README.

@paracycle
Copy link
Member Author

I think this is worth documenting in ActiveRecordColumns compiler and the README.

Agreed. I am happy to do that in a follow up PR.

@paracycle paracycle merged commit dcfb7da into main Jun 4, 2024
32 checks passed
@paracycle paracycle deleted the uk-at-compiler-options branch June 4, 2024 20:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants