【rails】gemを使ってタグ機能を実装する

#はじめに
act_as_taggrable_onというgemを使って簡易的なタグ機能を実装しようと思います。
エラーがでたりして複数の記事をみながら実装し時間がかかったので、1つにまとめて見やすいように備忘録としてこの記事を執筆します。

###用意するもの
シンプルな投稿機能は用意しておいてください。

###環境
windows10
ruby 2.6.6
rails 6.0

#実装
###1.gemをインストールする
```Gemfile.
gem 'acts-as-taggable-on', '~> 7.0'
```
```
$ bundle install
```

###2.テーブルを作成する
```
$ rails acts_as_taggable_on_engine:install:migrations
```
次に``rails db:migrate``をする前に、作成された6つのマイグレーションファイルのうち``○○○○_add_missing_unique_indices.acts_as_taggable_on_engine.rb``の以下の行をコメントアウトします。

```db/migrate/○○○○_add_missing_unique_indices.acts_as_taggable_on_engine.rb
AddMissingUniqueIndices.class_eval do
  def self.up
    add_index ActsAsTaggableOn.tags_table, :name, unique: true

    #remove_index ActsAsTaggableOn.taggings_table, :tag_id if index_exists?(ActsAsTaggableOn.taggings_table, :tag_id)
    # ↑上記をコメントアウト

    remove_index ActsAsTaggableOn.taggings_table, name: 'taggings_taggable_context_idx'
    add_index ActsAsTaggableOn.taggings_table,
              [:tag_id, :taggable_id, :taggable_type, :context, :tagger_id, :tagger_type],
              unique: true, name: 'taggings_idx'
  end

  def self.down
    remove_index ActsAsTaggableOn.tags_table, :name

    remove_index ActsAsTaggableOn.taggings_table, name: 'taggings_idx'

    add_index ActsAsTaggableOn.taggings_table, :tag_id unless index_exists?(ActsAsTaggableOn.taggings_table, :tag_id)
    add_index ActsAsTaggableOn.taggings_table, [:taggable_id, :taggable_type, :context], name: 'taggings_taggable_context_idx'
  end
end
```
そして、マイグレーションを行います。

```
$ rails db:migrate
```
※マイグレーションファイルを編集する前に``rails db:migrate``を行うと、エラーがでてきます。

###3.モデルとコントローラーに追加
```post.rb
class Post < ApplicationRecord
    acts_as_taggable #追加
end
```

```posts_controller.rb
class PostsController < ApplicationController
  def index
    @posts = Post.all
   #ここから追加
    if params[:tag_name]
      @posts = Post.tagged_with("#{params[:tag_name]}")
    end
   #ここまで
  end

 #省略

  private
  def post_params
    params.require(:post).permit(:body, :tag_list) #tag_list を追加
  end
end

```
###4.ビューの編集
投稿ページ

```new.html.erb
<%= form_for @post do |f| %>
  <div class="field">
    <%= f.label :投稿内容 %>
    <br>
    <%= f.text_area :body %>
  </div>

    #ここから追加
  　<div class="field">
    <%= f.label :タグ %>
    <%= f.text_field :tag_list, value: @post.tag_list %>
　　</div>
　　#ここまで

  <%= f.submit "投稿する" %>
<% end %>
```
投稿一覧ページ

```index.html.erb
<% @posts.each do |p| %>
    #省略
  <%= render 'posts/tag_list', tag_list: p.tag_list %> #追加
<% end %>
```
``_tag_list.html.erb``ファイルを作成

```_tag_list.html.erb
<% tag_list.each do |tag| %>
<%= link_to tag, posts_path(tag_name: tag) %>
<% end %>
```

これで完成です！
複数のタグを作成するためにはタグとタグをカンマで区切ります。

###区切り方をカンマから半角スペースにする方法
半角スペースなどで区切りたい場合は、``config/initializers`` に ``acts_as_taggable_on.rb`` を作成して、以下のように記述します。

```acts_as_taggable_on.rb
ActsAsTaggableOn.delimiter = ' '
```
その後、一度サーバー再起動すると半角スペースでタグを区切れるようになります。

#参考記事
[Rails | acts-as-taggable-on を使ったタグ機能の実装 | 備忘録](https://qiita.com/ddd555/items/e1caa8b73d118822a0a2)
[Railsにタグ機能をつける。acts-as-taggable-on使用](https://qiita.com/nakamura999/items/56c6426fc5dd640617ce)
[【Rails】acts-as-taggable-onの区切り文字の変更](https://qiita.com/tomoronn3/items/3d19c66023ab597dca59)
[acts-as-taggable-on導入時のエラー](https://teratail.com/questions/224720)