> ## Documentation Index
> Fetch the complete documentation index at: https://planetscale.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Automatic Rails migrations

<Tip>
  If you are using PlanetScale with a Rails application, go to your database's Settings page in the web app and enable
  "Automatically copy migration data." Select "Rails/Phoenix" as the migration framework. When enabled, this setting
  updates the *schema\_migrations* table each time you branch with the latest migration. If disabled, running
  *rake db:migrate* will try to run all migrations every time, instead of only the latest one.
</Tip>

## Introduction

In this tutorial, you're going to learn how Rails migrations work with the PlanetScale branching and deployment workflows.

<Note>
  Migration tracking works with any migration tool, not just Rails. For other frameworks, specify the migration table name on your database's Settings page.
</Note>

## Prerequisites

Follow the [Connect a Rails app](/vitess/tutorials/connect-rails-app) tutorial first. By the end, you will have:

* Installed the [PlanetScale CLI](https://github.com/planetscale/cli), Ruby, and the Rails gem
* Created a PlanetScale database named `blog`
* Started a new Rails app named `blog` with a migration creating a `Users` table
* Run the first Rails migration

### A quick introduction to Rails migrations

Rails tracks an application's migrations in an internal table called `schema_migrations`. At a high level, running `rake db:migrate` does the following:

* Rails looks at all of the migration files in your `db/migrate` directory.
* Rails queries the `schema_migrations` table to see which migrations have and haven't been run.
* Any migration that doesn’t appear in the `schema_migrations` table is considered pending and is executed by this task.

<Tip>
  When you merge a deploy request in PlanetScale, the *schema\_migrations* table in *main* is
  automatically updated with the migration data from your branch.
</Tip>

## Execute a Rails migration on PlanetScale

Rails migrations follow the PlanetScale [non-blocking schema change](/vitess/schema-changes) workflow. First, the migration is applied to a *development* branch, and then the development branch is merged into the `main` production branch with [safe migrations](/vitess/schema-changes/safe-migrations) enabled.

Let's add another table to your existing `blog` schema:

<Steps>
  <Step>
    Create an `add-posts-table` development branch from `main` in your database *blog*:

    ```bash theme={null}
    pscale branch create blog add-posts-table
    ```

    When the branch is ready, you can verify that the `schema_migrations` table is up-to-date with `main` by checking for the timestamp of your `Create Users` migration file. Your migration will have a different timestamp than the one shown here.

    Check the timestamp in your codebase:

    ```bash theme={null}
    ls db/migrate
    20211014210422_create_users.rb
    ```

    Connect to the new branch:

    ```bash theme={null}
    pscale shell blog add-posts-table
    ```

    Query the migration table:

    ```sql theme={null}
    blog/add-posts-table> select * from schema_migrations;
    +----------------+
    | version        |
    +----------------+
    | 20211014210422 |
    +----------------+
    ```
  </Step>

  <Step>
    Connect your development environment to the new branch:

    One way to do this is to create a new password for the `add-posts-table` branch and update `config/database.yml` with the new username, password, and host. Another is to use `pscale connect` to establish a secure connection on a local port. Since the `add-posts-table` branch won't be needed after the migration, let's use the `pscale connect` proxy.

    In a separate terminal, establish the connection:

    ```bash theme={null}
    pscale connect blog add-posts-table --port 3309
    ```

    Then, update `config/database.yml` to connect through the proxy:

    ```yaml theme={null}
    development:
      <<: *default
      adapter: trilogy
      database: blog
      host: 127.0.0.1
      port: 3309
    ```
  </Step>

  <Step>
    Create the second Rails migration and call it `CreatePosts`:

    ```bash theme={null}
    rails generate migration CreatePosts
    ```

    Find the new migration file in `db/migrate` and add a few details for the new Posts table:

    ```ruby theme={null}
    class CreatePosts < ActiveRecord::Migration[7.0]
      def change
        create_table :posts do |t|
          t.string :title
          t.text :content
          t.bool :published
          t.references :user
          t.timestamps
        end
      end
    end
    ```
  </Step>

  <Step>
    Run the CreatePosts migration:

    ```bash theme={null}
    rake db:migrate
    ```

    This command runs the new migration against your `add-posts-table` *development* branch.

    At this point, Rails creates the `posts` table and inserts another `timestamp` into the `schema_migrations` table on your development branch.

    You can verify the change in `schema_migrations` yourself:

    ```sql theme={null}
    blog/add-posts-table> select * from schema_migrations;
    +----------------+
    | version        |
    +----------------+
    | 20211014210422 |
    | 20220224221753 |
    +----------------+
    ```
  </Step>

  <Step>
    Open a deploy request for your `add-posts-table` branch, and deploy your changes to `main`.

    You can complete the deploy request either in the web app or with the `pscale deploy-request` command.

    ```bash theme={null}
    pscale deploy-request create blog add-posts-table
    ```

    ```bash theme={null}
    pscale deploy-request deploy blog 1
    ```

    To create the deploy request, PlanetScale looks at the differences between the schemas of `main` and `add-posts-table` and plans a `create table` statement to add the new table to `main`. When you deploy, PlanetScale runs that ` create table` statement and copies the second row from `schema_migrations` in `add-posts-table` to the `schema_migrations` table in `main`.\`
  </Step>

  <Step>
    Verify the changes in your `main` branch:

    In a `pscale` shell for `main` you can verify that the changes from `add-posts-table` were deployed successfully.

    ```bash theme={null}
    pscale shell blog main
    ```

    ```sql theme={null}
    blog/|⚠ main ⚠|> show tables;
    +----------------------+
    | Tables_in_blog       |
    +----------------------+
    | posts                |
    | schema_migrations    |
    | users                |
    +----------------------+

    blog/|⚠ main ⚠|> select * from schema_migrations;
    +----------------+
    | version        |
    +----------------+
    | 20220223232425 |
    | 20220224221753 |
    +----------------+
    ```
  </Step>
</Steps>

## Summary

In this tutorial, we learned how to use the PlanetScale deployment process with the Rails migration workflow.

## What's next?

Learn more about how PlanetScale allows you to make [schema changes](/vitess/schema-changes) to your production databases without downtime or locking tables.

## Need help?

Get help from [the PlanetScale Support team](https://planetscale.com/contact?initial=support), or join our [Discord community](https://pscale.link/community) to see how others are using PlanetScale.
