4
10

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.

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

Posted at

gemを使ったタグ機能実装 (備忘録)

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

↓導入編についてはこちら
Railsでタグ投稿機能実装(導入編)

スクリーンショット 2020-04-07 15.44.24.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]のカウントが増えていきます。

3.ビューファイル編集(一覧表示+タグの絞り込み)

続いて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_nametagged_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:)
挙動確認

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

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

Rails | acts-as-taggable-on を使ったタグ機能の実装 | 備忘録
acts-as-taggable-on Git Hub
Rails 5.2でタグ投稿機能の実装のためgem「acts-as-taggable-on」を使ってみた

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?