[Ruby on rails]タグ付け機能④タグにユーザー情報紐付け　マイページで投稿に紐付けたタグを表示

<h2>初めに</h2>
今回は、タグにユーザー情報を紐付けて、
マイページでそのユーザーが投稿に紐づけたタグを表示するようにします。

<h2>これまでの記事</h2>

https://qiita.com/ki_87/items/a344ea566c88b10b950c

https://qiita.com/ki_87/items/ae5d44af096df01ca587

https://qiita.com/ki_87/items/b7ceded18d473dc22f8f


<h2>完成イメージ</h2>

以下はマイページの一部です。

![スクリーンショット 2021-08-16 21.07.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/86acb053-6827-f36d-5a78-8e0b0c2902c0.png)

<h2>マイグレーションファイル</h2>

中間テーブルに外部キー追加します。
t.references :user, foreign_key: true　のところです。
これでユーザーidも保存させます。

```
class CreatePostTags < ActiveRecord::Migration[5.2]
  def change
    create_table :post_tags do |t|
      t.references :post, foreign_key: true
      t.references :tag, foreign_key: true
      t.references :user, foreign_key: true

      t.timestamps
    end
    # 同じタグを２回保存するのは
    add_index :post_tags, %i[post_id tag_id], unique: true
  end
end
```



<h2>アソシエーション記述</h2>

後から気づいたのですが、
タグとユーザーのアソシエーションは書かなくてもいける気がします。。。

```perl:user.rb
# タグのアソシエーション、中間テーブル
  has_many :post_tags,dependent: :destroy
  has_many :tags,through: :post_tags
```

```perl:Post_tga.rb
class PostTag < ApplicationRecord
  belongs_to :post
  belongs_to :tag
  belongs_to :user
  validates :post_id, presence: true
  validates :tag_id, presence: true
  validates :user_id, presence: true
end
```

```perl:tag.rb
# タグは複数のユーザーを持つ
  has_many :users, through: :post_tags
```

<h2>タグの保存時にユーザー情報も保存させる</h2>

あとはタグの保存にユーザー情報も保存してもらえればOKです！！
以下のタグ保存の記述は①で行っています。
今回の変更点は最後の一行です。

```
  def save_tag(sent_tags)
    # タグが存在していれば、タグの名前を配列として全て取得
    current_tags = tags.pluck(:name) unless tags.nil?
    # 現在取得したタグから送られてきたタグを除いてoldtagとする
    old_tags = current_tags - sent_tags
    # 送信されてきたタグから現在存在するタグを除いたタグをnewとする
    new_tags = sent_tags - current_tags

    # 古いタグを消す
    old_tags.each do |old|
      tags.delete　Tag.find_by(name: old)
    end

    # 新しいタグを保存
    new_tags.each do |new|
      new_post_tag = Tag.find_or_create_by(name: new)
      post_tags.new(user_id: user_id,tag_id: new_post_tag.id).save
    end
  end
```

 ```post_tags.new(user_id: user_id,tag_id: new_post_tag.id).save```
①の記事から、ここだけ変えています。
ここにどうやってuser_idを渡すのか分からず、エラーを出していましたが、
コントローラーで@post.user_id = current_user.idと記述してるので、
これ以上コントローラーに何か記載する必要も、viewから渡す必要もなく、
user_idって書いてあげればuser_idを渡せるそうです・・・。

<h2>Usersコントローラー</h2>

```perl:users_controller.rb
  def show
    @user = User.find(params[:id])
    @posts = @user.posts.where(status: true).order('created_at DESC').page(params[:page]).per(20)
    @point=@user.passive_points.all
    @posts_tag = @user.tags.order('created_at DESC').limit(15)
  end
```

@posts_tag = @user.tags.order('created_at DESC').limit(15)
でこのユーザーが投稿した記事に紐付いてるタグを出しています。

<h2>View</h2>

<% @posts_tag.each do |tag| %>でタグ取り出すと、
お花（2) お花(2) ご飯（３）　ご飯（３）　ご飯（３）となりますので、
重複するものは表示しないようにしています。

```
<div id="tag_box">
          <p style="font-size:15px;"><i class="fas fa-tags">最近の投稿に紐付けたタグ</i></p>
            <% if @posts_tag.present?%>
              <!--last_tagという箱を作成-->
              <% last_tag=nil %>
              <% @posts_tag.each do |tag| %>
              <!--タグが被ってなければ、名前表示　タグ被ってたら何もせず-->
                <%  if tag != last_tag %>
                  <span style="font-size:15px; margin:2px;"><%= link_to tag.name,search_tag_path(tag_id: tag.id),class:"btn btn-sm btn-outline-primary"%></span>
                <% end %>
              <!--今取り出したタグをlast_tagに入れる-->
                <%  last_tag = tag %>
              <% end %>
            <% else %>
              <p>投稿がありません。</p>
            <% end %>
        </div>
```

<h2>終わり</h2>
これでようやく複数タグとの戦いも終了です。
まだ理解が浅い部分も多々ありますが、色々と学べました！！