Railsでタグ投稿機能実装(実装編)

## gemを使ったタグ機能実装　(備忘録)
前回に引続き、gem 'acts-as-taggable-on'を使ったタグ機能の実装編になります。

↓導入編についてはこちら
[Railsでタグ投稿機能実装(導入編)](https://qiita.com/kazuhj/items/2913ab23d80b3ffe680b)

<img width="1014" alt="スクリーンショット 2020-04-07 15.44.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526620/c6a74fbf-412c-bad9-4c4f-7ea6d2694c53.png">


## 開発環境
Rails バージョン5.2.4.1
ruby バージョン2.5.1
acts-as-taggable-on バージョン　6.0.0
データベース　mySQL

## 実装内容

## 1.モデルとコントローラーに記述を追加
・タグ機能を実装したいモデルとコントローラーに下記を追加する

```content.rb
class Content < ApplicationRecord
  acts_as_taggable  #追加(acts-as-taggable-onの別名)
~
end
```

```contents_controller.rb
class ContentsController < ApplicationController
  before_action :set_group
  def new
    @content = Content.new
  end

  def create
    @content = @group.contents.new(content_params)
    @content.user_id = current_user.id 
    if @content.save
      redirect_to group_contents_path(@group), notice: '保存できました'
    else
      @content.images.new
      @contents = @group.contents.includes(:user)
      flash.now[:alert] = '内容を入力してください'
      render :new
    end
  end

  private
  
  def content_params
    #tag_listをpermitに追加
    params.require(:content).permit(:text, :title, :image, :tag_list).merge(user_id: current_user.id)
  end

  def set_group
    @group = Group.find(params[:group_id])
    @users = @group.users
    @user = current_user
  end
end
```
## 2.ビューファイル編集(保存ページ)

```new.html.haml
 # 略
= form_with model:[@group,@content], local:true do |f|
 # 略
  .form-contents__tag
    = f.label :tag_list
    = f.text_field :tag_list, value: @content.tag_list.join(","), class: "form-control", placeholder: 'テキストを入力してください'
```
スペースで区切りたい場合は、config/initializers以下に`acts_as_taggable_on.rb`を新規作成。

```acts_as_taggable_on.rb
ActsAsTaggableOn.delimiter = ' '
```

これでDBに値が保存されます!
tagsテーブルの[name]カラムに入力したタグと同じ名前があればレコードは増えずに、[taggings_count]のカウントが増えていきます。

## ３.ビューファイル編集(一覧表示＋タグの絞り込み)
続いてDBに保存されたタグを表示させます。

```contents_controller.rb
def index
  @contents = @group.contents.includes(:user,:tags)
  if params[:tag_name]
    @contents = Content.tagged_with("#{params[:tag_name]}")
  end
end
```
indexアクションにて一覧表示させます。
N+1問題を考慮して`includes(:tags)`を記述しましょう。
tagged_withメソッドを使用することで、`tag_name`に値が入っている場合は（タグをクリックされたら)受け取った`tag_name`を`tagged_with("タグ名")`のタグ名に入れて絞り込みを実行してくれます。
処理が実行されると、同じtag_nameを持ったタスクが一覧で表示される仕組みです。

```index.html.haml
# 略
  - @contents.each do |content|
    %ul.contents__left__group__content-tag
      関連タグ :
      = render 'shared/tag_list', tag_list: content.tag_list
```

```_tag_list.html.haml
- tag_list.each do |tag|
  = link_to tag, group_contents_path(@group,tag_name: tag), class: "tag-text"
```
render先にてeachの処理で一つ一つを独立させています。
また、link_toの記述でパスに`tag_name: tag`でタグの名前をコントローラーに渡して、
tagged_withメソッドで絞り込みを掛けています。

## 最後に
ひとまずタグの絞り込み機能まで実装しましたので、挙動確認用のGIFを貼っておきます。
(開発途中の個人アプリのため、cssの修正等はできていませんがご了承ください:bow:)
[挙動確認](https://i.gyazo.com/d800ecbb710e8d10650552404a0fc755.gif)

acts-as-taggable-onは他にもタグの使用頻度で検索を掛けれたりと便利なメソッドがあるので、一度リファレンスを見ていただけると良いかなと思います！

以下、導入編同様に参考にさせていただいた記事になります。

[Rails | acts-as-taggable-on を使ったタグ機能の実装 | 備忘録](https://qiita.com/ddgg7755/items/e1caa8b73d118822a0a2)
[acts-as-taggable-on Git Hub](https://github.com/mbleigh/acts-as-taggable-on)
[Rails 5.2でタグ投稿機能の実装のためgem「acts-as-taggable-on」を使ってみた](https://hirocorpblog.com/rails-5-2%E3%81%A7gem%E3%80%8Cacts-as-taggable-on%E3%80%8D%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%9F/)