2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Posted at

初めに

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

これまでの記事

完成イメージ

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

スクリーンショット 2021-08-16 21.07.44.png

マイグレーションファイル

中間テーブルに外部キー追加します。
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
    # 同じタグを2回保存するのは
    add_index :post_tags, %i[post_id tag_id], unique: true
  end
end

アソシエーション記述

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

user.rb
# タグのアソシエーション、中間テーブル
  has_many :post_tags,dependent: :destroy
  has_many :tags,through: :post_tags
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
tag.rb
# タグは複数のユーザーを持つ
  has_many :users, through: :post_tags

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

あとはタグの保存にユーザー情報も保存してもらえれば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を渡せるそうです・・・。

Usersコントローラー

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)
でこのユーザーが投稿した記事に紐付いてるタグを出しています。

View

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

<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>

終わり

これでようやく複数タグとの戦いも終了です。 まだ理解が浅い部分も多々ありますが、色々と学べました!!
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?