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

add: infer migration #1086

Merged
merged 5 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

* feat: smart migration generator. you can now generate migration based on naming them for creating a table, adding columns, references, join tables and more. [https://github.com/loco-rs/loco/pull/1086](https://github.com/loco-rs/loco/pull/1086)
* feat: `cargo loco routes` will now pretty-print routes
* fix: guard jwt error behind feature flag. [https://github.com/loco-rs/loco/pull/1032](https://github.com/loco-rs/loco/pull/1032)
* fix: logger file_appender not using the seperated format setting. [https://github.com/loco-rs/loco/pull/1036](https://github.com/loco-rs/loco/pull/1036)
Expand Down
103 changes: 73 additions & 30 deletions docs-site/content/docs/the-app/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ impl super::_entities::users::ActiveModel {

# Crafting models

## Migrations
## The model generator

To add a new model _you have to use a migration_.
To add a new model the model generator creates a migration, runs it, and then triggers an entities sync from your database schema which will hydrate and create your model entities.

```
$ cargo loco generate model posts title:string! content:text user:references
Expand Down Expand Up @@ -181,20 +181,24 @@ You can generate an empty model:
$ cargo loco generate model posts
```

You can generate an empty model **migration only** which means migrations will not run automatically:

Or a data model, without any references:

```
$ cargo loco generate model --migration-only posts
$ cargo loco generate model posts title:string! content:text
```

Or a data model, without any references:
## Migrations

Other than using the model generator, you drive your schema by *creating migrations*.

```
$ cargo loco generate model posts title:string! content:text
$ cargo loco generate <name of migration> [name:type, name:type ...]
```

This creates a migration in the root of your project in `migration/`.
You can now apply it:

You can apply it:

```
$ cargo loco db migrate
Expand All @@ -210,6 +214,63 @@ Loco is a migration-first framework, similar to Rails. Which means that when you

This enforces _everything-as-code_, _reproducibility_ and _atomicity_, where no knowledge of the schema goes missing.

**Naming the migration is important**, the type of migration that is being generated is inferred from the migration name.

### Create a new table

* Name template: `Create___`
* Example: `CreatePosts`

```
$ cargo loco g migration CreatePosts title:string content:string
```

### Add columns

* Name template: `Add___To___`
* Example: `AddNameAndAgeToUsers` (the string `NameAndAge` does not matter, you specify columns individually, however `Users` does matter because this will be the name of the table)

```
$ cargo loco g migration AddNameAndAgeToUsers name:string age:int
```

### Remove columns

* Name template: `Remove___From___`
* Example: `RemoveNameAndAgeFromUsers` (same note exists as in _add columns_)

```
$ cargo logo g migration RemoveNameAndAgeFromUsers name:string age:int
```

### Add references

* Name template: `Add___RefTo___`
* Example: `AddUserRefToPosts` (`User` does not matter, as you specify one or many references individually, `Posts` does matter as it will be the table name in the migration)

```
$ cargo loco g migration AddUserRefToPosts user:references
```

### Create a join table

* Name template: `CreateJoinTable___And___` (supported between 2 tables)
* Example: `CreateJoinTableUsersAndGroups`

```
$ cargo loco g migration CreateJoinTableUsersAndGroups count:int
```

You can also add some state columns regarding the relationship (such as `count` here).

### Create an empty migration

Use any descriptive name for a migration that does not fall into one of the above patterns to create an empty migration.

```
$ cargo loco g migration FixUsersTable
```

### Down Migrations

If you realize that you made a mistake, you can always undo the migration. This will undo the changes made by the migration (assuming that you added the appropriate code for `down` in the migration).
Expand Down Expand Up @@ -247,27 +308,11 @@ $ cargo loco generate model movies long_title:string added_by:references:users d
* reference added_by is in singular, the referenced model is a model and is plural: `added_by:references:users`
* column name in snake case: `long_title:string`

### Naming migrations

There are no rules for how to name migrations, but here's a few guidelines to keep your migration stack readable as a list of files:

* `<table>` - create a table, plural, `movies`
* `add_<table>_<field>` - add a column, `add_users_email`
* `index_<table>_<field>` - add an index, `index_users_email`
* `alter_` - change a schema, `alter_users`
* `delete_<table>_<field>` - remove a column, `delete_users_email`
* `data_fix_` - fix some data, using entity queries or raw SQL, `data_fix_users_timezone_issue_315`

Example:

```sh
$ cargo loco generate migration add_users_email
```

### Migration Definition

### Add or remove a column

Adding a column:
**Add a column**

```rust
manager
Expand All @@ -280,7 +325,7 @@ Adding a column:
.await
```

Dropping a column:
**Drop a column**

```rust
manager
Expand All @@ -293,8 +338,7 @@ Dropping a column:
.await
```

### Add index

**Add index**

You can copy some of this code for adding an index

Expand All @@ -310,8 +354,7 @@ You can copy some of this code for adding an index
.await;
```

### Create a data fix

**Create a data fix**

Creating a data fix in a migration is easy - just use SQL statements as you like:

Expand Down
Loading
Loading