【Rails】annotateの使い方

# `annotate`とは
各モデルのスキーマ情報をファイルの先頭もしくは末尾にコメントとして書き出してくれるGemです。
どんなカラムがあったっけ？ってなった時にいちいち`db/schema.rb`を見に行く手間を省けます。
さらに、`config/routes.rb`にルーティング情報を書き出してくれる機能もあります。
いちいち`rails routes`を実行して確認する手間が省けますね。ありがたい。

# 環境
- Rails 5.2.3
- Ruby 2.6.3
- annotate 2.7.5

# 準備
`Gemfile`に以下を記述して、`bundle install`。

```ruby:Gemfile
gem 'annotate'
```

```bash
$ bundle install
```

# 設定ファイルを作成
以下のコマンドを実行すると`lib/tasks/auto_annotate_models.rake`が作成されます。
このファイルで設定を色々変えられます。

```bash
$ bundle exec rails g annotate:install
```

#  モデルのスキーマ情報を書き出す
ここまでで既に基本的な機能は有効になっています。
試しにモデルを作成してみます。

```bash
$ rails g model User name:string email:string age:integer
$ rails db:migrate
```

`rails db:migrate`を実行すると`Annotated (3): app/models/user.rb, ...`というメッセージが表示され、自動的にファイルの先頭にスキーマ情報が書き出されます。
カラムを新しく追加した時や、変更した時などもちゃんと書き出してくれます。

```ruby:app/models/user.rb
# == Schema Information 
#
# Table name: users
#
#  id         :integer          not null, primary key
#  age        :integer
#  email      :string
#  name       :string
#  created_at :datetime         not null
#  updated_at :datetime         not null
#
 
class User < ApplicationRecord
end
```

便利！

# 手動でannotateを実行する
手動で実行したい場合は以下のコマンドを実行するだけで大丈夫です。

```bash
$ bundle exec annotate
$ bundle exec annotate --routes # ルーティング情報(後述)を書き出す
$ bundle exec annotate --exclude fixtures # fixturesには書き出さない
$ bundle exec annotate --exclude tests,fixtures,factories,serializers # modelファイルのみに書き出す
```

# 書き出されたコメントを削除する
`annotate`によって書き出されたコメントを削除したい場合は以下のコマンドを実行すればコメントが削除されます。

```bash
$ bundle exec annotate --delete
$ bundle exec annotate --routes --delete # ルーティング情報(後述)を削除する
```

## スキーマ情報をファイルの末尾に書き出してほしい場合
設定ファイルの `position_in_class` を `'after'` に変更します。

```diff_ruby:lib/tasks/auto_annotate_models.rake
- 'position_in_class' => 'before'
+ 'position_in_class' => 'after'
```
こうすればファイルの先頭ではなく末尾にスキーマ情報が書き出されるようになります。

# `rails db:migrate`の時に勝手にコメントを書いて欲しくない場合
設定ファイルの `skip_on_db_migrate` を `'true'` に変更します。

```diff_ruby:lib/tasks/auto_annotate_models.rake
- 'skip_on_db_migrate' => 'false'
+ 'skip_on_db_migrate' => 'true'
```

こうすれば`rails db:migrate`を実行しても自動でスキーマ情報が書き出されなくなります。
また、設定を変更しなくても実行時に`ANNOTATE_SKIP_ON_DB_MIGRATE`を設定すれば自動で書き出されません。

```bash
$ ANNOTATE_SKIP_ON_DB_MIGRATE=1 rails db:migrate
```

# ルーティング情報を書き出す
実は`annotate`はモデルのスキーマ情報だけでなく、`config/routes.rb`にルーティング情報も書き出してくれます。
ルーティング情報を書き出してほしい場合は以下のコマンドを実行します。

```bash
$ bundle exec annotate --routes
```

```ruby:config/routes.rb
# == Route Map
#
#                    Prefix Verb URI Pattern                                                                              Controller#Action
#        rails_service_blob GET  /rails/active_storage/blobs/:signed_id/*filename(.:format)                               active_storage/blobs#show
# rails_blob_representation GET  /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
#        rails_disk_service GET  /rails/active_storage/disk/:encoded_key/*filename(.:format)                              active_storage/disk#show
# update_rails_disk_service PUT  /rails/active_storage/disk/:encoded_token(.:format)                                      active_storage/disk#update
#      rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format)                                           active_storage/direct_uploads#create
 
Rails.application.routes.draw do
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
```

# まとめ
便利。
間違っている箇所などありましたらご指摘お願いします。

# 参考
[公式リポジトリ](https://github.com/ctran/annotate_models)