初めに
今回は、タグにユーザー情報を紐付けて、 マイページでそのユーザーが投稿に紐づけたタグを表示するようにします。これまでの記事
完成イメージ
以下はマイページの一部です。
マイグレーションファイル
中間テーブルに外部キー追加します。
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
アソシエーション記述
後から気づいたのですが、
タグとユーザーのアソシエーションは書かなくてもいける気がします。。。
# タグのアソシエーション、中間テーブル
has_many :post_tags,dependent: :destroy
has_many :tags,through: :post_tags
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
# タグは複数のユーザーを持つ
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コントローラー
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>