0
0

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 1 year has passed since last update.

【Rails】 acts_as_taggable_onでハッシュタグ機能を作る

Posted at

概要

タグ機能をさくっと作ることができるgem
acts_as_taggable_onを利用してハッシュタグ機能を作ります。

※2つの参考記事を組み合わせて多少手を加えただけです
https://qiita.com/d510/items/e1caa8b73d118822a0a2
https://qiita.com/MitsuTurtle/items/614b154641ab4e4b56ba

開発環境

Ruby 3.0.2
Rails 7.0.0
Bootstrap 5
slim

前提条件

既存のPostモデルがあるものとします。
Postのスキーマ情報

schema.rb
create_table "posts", force: :cascade do |t|
    t.string "title"
    t.text "content"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
end

このPostモデルにハッシュタグ機能を追加します。

acts_as_taggable_onの準備

Gemfileに追加してbundle install、マイグレーションします。

acts_as_taggable_onをGemfileに追加

Gemfile
gem 'acts-as-taggable-on' #追加
bundle install

マイグレーション

rails acts_as_taggable_on_engine:install:migrations
rails db:migrate

モデルとコントローラーを編集

post.rb
class Post < ActiveRecord::Base
  acts_as_taggable #追加
end
posts_controller.rb
class PostsController < ApplicationController

#(省略)
	
  private

  def post_params
    params.require(:post).permit(:title, :content, :tag_list) 
    #ストロングパラメーターにtag_listを追加
  end	
end

これでacts_as_taggable_onを使う準備は完了です。

ハッシュタグ登録機能を追加

正規表現で半角「#」のついた文字列を探し、タグに追加します。

モデルを編集

post.rb
after_create do
   hashtags  = self.content.scan(/[#][\w\p{Han}ぁ-ヶヲ-゚ー]+/)
   hashtags.uniq.map do |hashtag|
       tag = tag = hashtag.downcase.delete('#')
       tag_list << tag
   end
end

before_update do
   tag_list.clear
   hashtags = self.content.scan(/[#][\w\p{Han}ぁ-ヶヲ-゚ー]+/)
   hashtags.uniq.map do |hashtag|
       tag = tag = hashtag.downcase.delete('#')
       tag_list << tag
   end
end

タグをクリックで投稿を絞り込み

クエリパラメーター「tag_name」で投稿を絞り込めるようにします。

posts_controller.rb
def index
    @posts = Post.all   
    @posts = Post.tagged_with(params[:tag_name]) if params[:tag_name]
end

ヘルパーを作成

posts.helper.rb
module PostsHelper
    def render_with_hashtags(content)
        content.gsub(/[#][\w\p{Han}ぁ-ヶヲ-゚ー]+/){|word| link_to word, posts_path(tag_name: word.delete("#"))}.html_safe
    end
end

一覧ページに表示させる

views/posts/index.html.slim
    -@posts.each do |post|
        tr
            td = post.id
            td = post.title
            td = render_with_hashtags(post.content)
            td = link_to 'show', post_path(post), class: 'btn btn-primary'
            td = link_to 'edit', edit_post_path(post), class: 'btn btn-primary'
            td = link_to 'destroy', post_path(post), data: {turbo_method: 'delete', turbo_confirm: 'Are you sure?'}, class: 'btn btn-danger delete'

詳細ページに表示させる

views/posts/show.html.slim
div.card
    div.card-header
        h4 =@post.title
    div.card-body
        p.card-text
           =simple_format(render_with_hashtags(@post.content))

詳細表示
スクリーンショット 2023-01-22 13.08.23.png

タグの名前をクリックでタグがついた投稿を絞り込むことができます。
一覧表示
スクリーンショット 2023-01-22 16.40.02.png

タグの名前をクリックした時のURL
http://localhost:3000/posts?tag_name=ハッシュタグ1

参考

https://qiita.com/d510/items/e1caa8b73d118822a0a2
https://qiita.com/MitsuTurtle/items/614b154641ab4e4b56ba
https://github.com/mbleigh/acts-as-taggable-on

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?