Rails マイグレーションの廃止とRidgepoleの導入・利用方法

# 概要
<ul>
 	<li><a href="https://lismoa.com">lismoa</a>ついにマイグレーションやめるってよ</li>
 	<li>クックパッドが使ってるRidgepoleというスキーマ管理用のコマンドラインツールを使おうぜ</li>
 	<li>Ridgepoleクックパッドのエンジニアが作っとるやん</li>
 	<li>結構使いやすいやん</li>
 	<li>使い方解説します</li>
</ul>

# マイグレーション廃止の理由
昨今の<a href="https://lismoa.com">lismoa</a>多機能化に伴いRailsプロジェクトが複数に分裂してきました。
現在のプロジェクトは以下の4つです。

- app（本体）
- batch（バッチ用）
- api（他システム連携用）
- admin（管理用）

これらのプロジェクト全てで同じDBを参照しています。
そうすると各プロジェクトごとのマイグレーションファイルを同状態に揃えないとDBの完全な整合性が取れないという問題が生じてしまいます。
この対応として、今までは定期的に全プロジェクトのマイグレーションファイルとモデルを揃える作業をしていました。

<strong>これが非常にナンセンスで手間がかかる！</strong>
<strong>マイグレーションファイルが増えすぎててわやくちゃ！</strong>

ということでRidgepoleの導入に至ったわけです。
# そもそもRidgepoleとは？
スキーマ管理用のコマンドラインツールだそうです。
シンプルに言えば簡単にテーブルの作成、変更、削除ができる便利なものです。
クックパッドが使ってるから信頼していいでしょう。（盲目）
というか作ったのがクックパッドですし。
詳しくはこちらを参照してください。
<a href="http://techlife.cookpad.com/entry/2014/08/28/194147" target="_blank" rel="noopener">クックパッドにおける最近のActiveRecord運用事情</a>
# 利用方法
今回は例として<code>users</code>テーブルを作成します。
## 導入
gemが公開されているのでGemfileに記述します。
<a href="https://github.com/winebarrel/ridgepole" target="_blank" rel="noopener">ridgepole</a>
バージョンは必要であれば指定しましょう。

```rb
# Gemfile
gem 'ridgepole'
```
そしていつもの<code>bundle install</code>を実行。
## モデルジェネレート
マイグレーションは不要なのでスキップするのを忘れないように！
<pre class="command-line"><code class="language-markup">$ rails g model amazonFlatFile --skip-migration</code></pre>
## テーブルの定義ファイル
詳しい記述方法は以下を参照してください。
<a href="https://github.com/winebarrel/ridgepole" target="_blank" rel="noopener">ridgepole</a>
<h3>1ファイルで管理する場合</h3>
<code>Schemafile</code>にテーブル定義を記述します。

```rb
# /{project}/db/Schemafile
create_table "users", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
  t.bigint "team_id"
  t.string "name"
  t.string "email"
  t.datetime "created_at", default: ->; { "CURRENT_TIMESTAMP" }, null: false
  t.timestamp "updated_at", default: ->; { "CURRENT_TIMESTAMP" }, null: false
  t.index ["team_id"], name: "index_team_id_on_users"
end
```
以上で準備完了。
<h3>テーブルごとにファイル分けする場合</h3>
<code>/{project}/db</code>配下に``<code>.schema</code>拡張子のファイルを作成します。

```rb
# /{project}/db/users.schema
create_table "users", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
  t.bigint "team_id"
  t.string "name"
  t.string "email"
  t.datetime "created_at", default: ->; { "CURRENT_TIMESTAMP" }, null: false
  t.timestamp "updated_at", default: ->; { "CURRENT_TIMESTAMP" }, null: false
  t.index ["team_id"], name: "index_team_id_on_users"
end
```
Schemafileでrequireします。

```rb
# /{project}/db/Schemafile
require 'users.schema'
```
以上で準備完了。
## 実行
以下のコードを実行します
<code>-E development</code>の部分は適宜変更しましょう。
<pre class="command-line"><code class="language-markup">$ bundle exec ridgepole -c config/database.yml -E development --apply -f db/Schemafile</code></pre>
## 結果
成功するとこんな感じになります。
<pre class="command-line" data-output="2-7"><code class="language-markup">$ bundle exec ridgepole -c spec/dummy/config/database.yml -E development --apply -f db/Schemafile
Apply `db/Schemafile`
-- create_table("amazon_flat_files", {:options=&gt;"ENGINE=InnoDB DEFAULT CHARSET=utf8"})
-&gt; 0.0308s
-- add_index("amazon_flat_files", ["sales_platform_id"], {:name=&gt;"index_amazon_flat_files_on_sales_platform_id"})
-&gt; 0.0173s</code></pre>

いっつそーいーじー
## 備考
カラムの削除・追加、テーブルの削除などはスキーマファイルいじるだけでいい。
# 所感
使ってみると思ったより快適で満足しています。
早くやればよかったんじゃ...