RailsでBootstrapTagsInputを使ったタグ管理機能を実装する

# 0. はじめに
こんにちは。toramaruJPです(｀・ω・´)
今回はオリアプに実装したタグ機能について書いていこうと思います。
BootstrapTagsInputを使用した実装になりますが、他にもありますので、下記のURL等見てみて下さいませ！！

＜参考URL＞

- https://ruby-rails.hatenadiary.com/entry/20150225/1424858414

- http://notsobad-jp.tumblr.com/post/80673191669/railsでいい感じのタグ管理するならacts-as-taggableとjquery-tags-inp

# 1. 実装概要
### (1) タグ機能を実装する為の準備をしよう！
### (2) タグ機能を実装しよう！

# 2. 実装詳細
## (1) タグ機能を実装する為の準備をしよう！
### (a) アプリを立ち上げよう！
開発で使用するバージョンは以下の通りです。

```
Rails v5.1.6
ruby v2.3.1
```

下記コマンドで現在のバージョンを確認できます。

```
$ ruby -v
$ rails -v
```

rails newコマンドを使用してアプリの立ち上げを行います。

```
$ rails _5.1.6_ new tagSample -d postgresql
```

tagSampleディレクトリに移動します。

```
$ cd tagSample
```

config/database.ymlファイルを編集します。

```:config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  template: template1
```

データベースを作成します。

```
$ rails db:create
```

下記のコマンド実行後、"http://localhost:3000/"
にアクセスをして、サーバーが立ち上がるか確認しましょう。

```
$ rails s
```

簡易なBlog機能を作成します。

```
$ rails g scaffold Post title:string context:text
```

```
$ rails db:migrate
```

### (b) acts-as-taggable-onをインストールしよう！

acts-as-taggable-onというgemをインストールします。

```:Gemfile
gem 'acts-as-taggable-on'
```

```
$ bundle install
```

acts-as-taggable-onを使用する際に必要なテーブルを作成します。

```
$ rails acts_as_taggable_on_engine:install:migrations
```

```
$ rails db:migrate
```

### (c) BootstrapTagsInputを使用する際に必要なファイルをコピーしよう！

下記のサイトの"Download"から、下記ファイルを下記ディレクトリへコピーしましょう。
https://bootstrap-tagsinput.github.io/bootstrap-tagsinput/examples/

- bootstrap-tagsinput.css(app/assets/stylesheets)
- bootstrap-tagsinput.min.js(app/assets/javascripts)
- bootstrap-tagsinput.min.js.map(app/assets/javascripts)

下記ファイルに下記記述を追加しましょう。

```:application.js
//= require bootstrap-tagsinput.min
```
※　//= require_tree .がある場合は、その上に記述しましょう。

```:application.css
*= require bootstrap-tagsinput
```
※　*= require_tree .がある場合は、その上に記述しましょう。

### (d) Bootstrapをインストールしよう！！

前提として、Bootstrapをインストールする必要があるので、下記などを参考にしてBootstrapをインストールしましょう。

＜参考URL＞

https://qiita.com/fuqda/items/c5756b8f56dcc238c110

## (2) タグ機能を実装しよう！

### acts-as-taggable-onを使用しよう！

タグリストが一つ必要な場合には、下記ファイルに下記の記述を追加します。

```:app/models/post.rb
  acts_as_taggable_on :labels # post.label_list が追加される
  acts_as_taggable            # acts_as_taggable_on :tags のエイリアス
                              # つまり、post.tag_list が追加される
```

タグリストが複数(今回は二つ)必要な場合には、下記ファイルに下記の記述を追加します。

```:app/models/post.rb
  acts_as_taggable_on :skills, :interests
```

PostsコントローラーのStrongParametersでこれらのパラメーターを受け取れるようにします。

```:app/controllers/posts_controller.rb
def post_params
  params.require(:post).permit(:title, :context, :skill_list, :interest_list)
end
```

画面からそれぞれのタグリストをテキストフィールドでカンマ区切りで入力できるようにします。

```:app/views/posts/_form.html.erb
  省略

  <div class="field">
    <%= f.label :title, "タイトル" %><br>
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :skill_list, "スキル・特技" %><br>
    <%= text_field_tag 'post[skill_list]', @post.skill_list.join(','), "data-role" => "tagsinput" %>
  </div>
  <div class="field">
    <%= f.label :interest_list, "興味・関心" %><br>
    <%= text_field_tag 'post[interest_list]', @post.interest_list.join(','), "data-role" => "tagsinput" %>
  </div>
　　　　<div class="field">
    <%= f.label :context, "内容" %><br>
    <%= f.text_field :context %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>

　　　　省略
```

入力したタグを画面に表示できるようにします。

```:app/views/posts/index.html.erb
<p id="notice"><%= notice %></p>

<h1>Posts</h1>

<table>
  <thead>
    <tr>
      <th>Title</th>
      <th>Context</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @posts.each do |post| %>
      <tr>
        <td><%= post.title %></td>
        <td><%= render 'posts/tag_list', tag_list: post.skill_list %></td>
        <td><%= render 'posts/tag_list', tag_list: post.interest_list %></td>
        <td><%= post.context %></td>
        <td><%= link_to 'Show', post %></td>
        <td><%= link_to 'Edit', edit_post_path(post) %></td>
        <td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Post', new_post_path %>
```

```:app/views/posts/_tag_list.html.erb
<% tag_list.each do |tag| %>
  <span class="label label-primary"><%= tag %></span>
<% end %>
```

※ bootstrap4をインストールしている場合には、上記ファイルの"label label-primary"部分を"badge badge-primary"に変更する必要がある。

※ さらに、bootstrap4をインストールしている場合には、下記ファイルの該当部分をreturn　"badge badge-primary"に変更する必要がある。

```:bootstrap-tagsinput.min.js
省略
　　　　　　
return　"label label-primary"
　　　　　　
省略
```

# 3. 最後に

これで２記事目になりますが、ちゃんと書こうとすると時間取られますねこれ(｀・ω・´)
定期的に出すために限定共有記事とかを使って、日常的にストックを貯めるようにしていきたいです！！
分量も少ない記事も作りたいと思います！！

以上になります！　何か改善点等ありましたら、指摘して頂くと嬉しいです(*´꒳`*)