[Rails]schema管理のgem ridgepoleを使ってみた

### 前提
記事を書いている私は現役のエンジニアではなくエンジニアを目指して学習中の者です。
よって、気をつけてはいますが記述内容には誤った内容が含まれている危険性があります。
その為この記事は参考程度に読んで頂き詳しい内容は公式の記述を参考にすることをおすすめします。

### この記事で実装すること
Ridgepoleというgemを使ってschema管理を実装します。
実際にPF等で使ったとかではなく、好奇心で触ってみたといったレベル感なので深堀りはしてないです。

### Ridgepoleとは・何がいいの？
クックパッドの人が開発したRailsのスキーマ管理用のコマンドラインツールのことです。
Railsのデフォルトで設定されているマイグレーションではテーブル内容に変更があった場合に
- 変更のためのmigrationファイルを作成するコマンドを実行
- ファイル内容を編集
- ``rails db:migrate``を実行

のステップが必要ですがRidgepoleは直接スキーマファイルを変更してコマンドを変更すればテーブル内容を変更できます。
他にもテーブルごとにスキーマファイルを分けれるのでチーム開発における作業のバッティングが起こりにくいなどの利点もあるそうです。
詳しくは[公式記事](https://techlife.cookpad.com/entry/2014/08/28/194147)に書かれています。

### 使用技術
Ruby 3.1.2
Rails 6.1.6
PostgreSQL


### 実装手順
gemのGithubを見た限りはmysqlで使用するのが無難そうです。
しかし、今回PostgreSQLを使ってもちゃんと動いたのでこちらでも問題さなそうです。
[Ridgepoleのgithub](https://github.com/ridgepole/ridgepole)

簡易的なCRUDアプリを作成した前提で実装していきます。

##### 1, gemをインストールする
gemfileに以下を追加して``bundle install``を実行します。
```
gem 'ridgepole'
```

##### 2, Schemafileファイルを作成する
schema情報を書き込むSchemafileファイルを作成します。
ルートディレクトリに設置してもいいのですが、dbディレクトリ配下に作った方がわかりやすいと思ったのでdbディレクトリの中にファイルを作成します。
[![Image from Gyazo](https://i.gyazo.com/6a48e8e3751c35c29775dc9a20be8808.png)](https://gyazo.com/6a48e8e3751c35c29775dc9a20be8808)
これで準備は完了です。あとはSchemafileファイルにテーブル情報を書いていくだけです。

##### 3, Schemafileファイルを編集する
試しにSchemafileファイルを以下のように編集してみます。
```ruby
create_table :tests, id: :bigint, force: :cascade, charset: 'utf8mb4' do |t|
  t.string  :name, null: false, default: ''
  t.string  :body, null: false
end
```
ファイルの編集が完了したら以下のコマンドを実行します。
```
$ bundle exec ridgepole --config config/database.yml --env development --file db/Schemafile --apply
```
これだけでテーブルの作成が完了です！

実際にテーブルが作成されているからdbで確認してみましょう。
```
# デフォルトのデータベースに接続
$ psql -d postgres

# データベース一覧を表示
$ \l

# データベースを選択
$ \c test_app_development(データベース名)

# テーブル一覧の表示
$ \dt;
             List of relations
 Schema |  Name   | Type  |     Owner
--------+---------+-------+----------------
 public |  tests  | table | owner_name
(1 row)

# テーブル構造の表示
$ \d tests;
Table "public.tests"
 Column |       Type        | Collation | Nullable |               Default
--------+-------------------+-----------+----------+-------------------------------------
 id     | bigint            |           | not null | nextval('tests_id_seq'::regclass)
 name   | character varying |           | not null | ''::character varying
 body   | character varying |           | not null |
Indexes:
    "tests_pkey" PRIMARY KEY, btree (id)
```
ちゃんとSchemafileファイルに書いた内容のテーブルとカラムが作成されていることが確認できます。


##### 4, カラムの変更・テーブルの削除追加
テーブルに関する変更はSchemafileファイルを編集してコマンドを実行するだけです！
試しにカラムやテーブルの追加や編集を行ってみます。
- カラムの追加
先ほどのSchemafileファイルにageというカラムを追加して``bundle exec ridgepole --config config/database.yml --env development --file db/Schemafile --apply``を実行します。
```ruby
create_table :authors, id: :bigint, force: :cascade, charset: 'utf8mb4' do |t|
  t.string  :name, null: false, default: ''
  t.string  :body, null: false
　　　　t.integer :age, null: false
end
```
データベース上で確認するとちゃんとカラムが追加されていることがわかります。
```
test_app_development=# select * from tests;
 id | name | body| age
----+------+-----+-----
(0 rows)
```

- テーブルの追加
Schemafileファイルにtweetsというテーブルを追加して``bundle exec ridgepole --config config/database.yml --env development --file db/Schemafile --apply``を実行します。
```ruby
create_table :tests, id: :bigint, force: :cascade, charset: 'utf8mb4' do |t|
  t.string  :name, null: false, default: ''
  t.string  :body, null: false
end

create_table :tweets, id: :bigint, force: :cascade, charset: 'utf8mb4' do |t|
  t.string  :name, null: false, default: ''
  t.string  :body, null: false
end
```
データベースを確認してみるとtweetsテーブルが追加されています。
```
test_app_album_development-# \dt;
             List of relations
 Schema |  Name   | Type  |     Owner
--------+---------+-------+----------------
 public | tests   | table | owner_name
 public | tweets  | table | owner_name
(2 rows)
```



以上でridgepoleを使ったスキーマ管理の説明を終わります。
マイグレートで管理していた時はミスがあった場合に修正するのが手間でしたがridgepoleを使うと簡単に修正ができて便利ですね！
初学者なので何か間違い等を見つけましたらご指摘頂けると助かります！