Skip to content

Commit

Permalink
Improve readme
Browse files Browse the repository at this point in the history
  • Loading branch information
ka8725 committed Dec 29, 2023
1 parent 8ff603b commit 2d79e33
Showing 1 changed file with 31 additions and 21 deletions.
52 changes: 31 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,35 @@

# ActualDbSchema

Keep Rails DB schema consistent while switching between branches with no additional actions.
Keep consistent DB schema across branches in your Rails project. Just install `actual_db_schema` gem and run `db:migrate` in your branch as usual. No additional steps needed.

## Why ActualDbSchema?

To grasp the purpose of this gem and the issue it addresses, review the problem definition outlined below.

### The problem definition

Imagine you're working on **branch A**. You add a not-null column to a database table with a migration. You run the migration. Then you switch to **branch B**. The code in **branch B** isn't aware of this newly added field. When it tries to write data to the table, it fails with an error `null value provided for non-null field`. Why? The existing code is writing a null value into the column with a not-null constraint.

Here's an example of this error:

ActiveRecord::NotNullViolation:
PG::NotNullViolation: ERROR: null value in column "log" of relation "check_results" violates not-null constraint
DETAIL: Failing row contains (8, 46, success, 2022-10-16 21:47:21.07212, 2022-10-16 21:47:21.07212, null).

Furthermore, the `db:migrate` task on **branch B** generates an irrelevant diff on the `schema.rb` file, reflecting the new column added in **branch A**.

To fix this, you need to switch back to **branch A**, find the migration that added the problematic field (we'll call it a *phantom migration*), and roll it back. It's a pain, especially if you have a lot of branches in your project, because you have to remember which branch the *phantom migration* is in and then manually roll it back.

With `actual_db_schema` gem you don't need to care about that anymore. It saves your time doing all this dirty stuff for you behind the scene automatically.

### How it solves the issue

This gem stores all run migrations with their code in the `tmp/migrations` folder. Whenever you perform a schema dump, it rolls back the *phantom migrations*.

The *phantom migrations* list is the difference between the migrations you've executed (in the `tmp/migrations` folder) and the current ones (in the `db/migrate` folder).

Therefore, all you do is run rails `db:migrate` in your current branch. `actual_db_schema` will ensure the DB schema is up-to-date. You'll never have an inaccurate `schema.rb` file again.

## Installation

Expand All @@ -20,28 +48,10 @@ And then execute:

## Usage

TLTR; Just run `rails db:migrate` inside the current branch.

In **branch A** I add a mandatory (not null) field into DB via migration and run it.
Then I switch to another **branch B**. This branch's code is not aware of that field.
As the result, the code is failing with an error "null value provided for non-null field".
Moreover, a DB rake task generates a diff on `schema.rb` that's not relevant to this branch.
I can switch to **branch A** and roll back the migration, but I need to remember that branch or waste time on it.

Some example of this error:

ActiveRecord::NotNullViolation:
PG::NotNullViolation: ERROR: null value in column "log" of relation "check_results" violates not-null constraint
DETAIL: Failing row contains (8, 46, success, 2022-10-16 21:47:21.07212, 2022-10-16 21:47:21.07212, null).

This gem saves all run migrations inside `tmp/migrations` folder.
Every run of schema dump (that's a dependency of `db:migrate` task as well) rolls back the "unknown" for the current branch migrations
looking into the `tmp/migrations` folder.

You just need to run `rails db:migrate` in the current branch to actualize the DB schema. With its hand, you will never have wrongly generated `schema.rb`.
Just run `rails db:migrate` inside the current branch.

> **Warning**
> This solution implies that all migrations are reversible. The cases with irreversible migrations should be solved manually. At the moment, these migrations are ignored by the gem and you will see a warning if some migrations can't roll back automatically.
> This solution implies that all migrations are reversible. The irreversible migrations should be solved manually. At the moment, the gem ignores them. You will see a warning if some migrations can't roll back automatically.
## Development

Expand Down

0 comments on commit 2d79e33

Please sign in to comment.