じぶんメモ

プログラミングのメモ、日常のメモとか。

Railsでタグ機能を実装する。

Railsでデータにタグ付けさせる昨日の実装方法について調べた。 acts-as-taggable-onというGemを使えば良さそう。

インストール

まずはbundle installでGemをいれる。

gem 'acts-as-taggable-on', '~> 3.4'

タグ付けに必要なテーブルを作成。

tomy2002:~/workspace $ rake acts_as_taggable_on_engine:install:migrations
tomy2002~/workspace $ rake db:migrate

使い方

モデルへの設定

タグ付けしたいモデルに、acts_as_taggableを宣言

class LiveHouse < ActiveRecord::Base
  # タグ機能の実装
  acts_as_taggable_on :labels # post.label_list が追加される
  acts_as_taggable            # acts_as_taggable_on :tags のエイリアス
end

こうすることで、live_house.tag_listや、live_house.label_listというメソッドを使用することができる。

タグの登録・取得・削除

# タグの登録
live_house.tag_list.add("Rock")  # "Rock"タグを追加する
live_house.tag_list.add("Rock", "Pops") # 複数のタグを追加する

# タグの取得
live_house.tag_list #["Rock", "Pops"]を取得

# タグの削除
live_house.tag_list.remove("Rock") # "Rock"タグを削除する
live_house.tag_list.clear                 # すべてのタグを削除する

# 最も使われているタグを配列で取得
ActsAsTaggableOn::Tag.most_used #引数を省略するとデフォルトで20件まで取得する。
ActsAsTaggableOn::Tag.most_used(3)

# 最も使われていないタグを配列で取得
ActsAsTaggableOn::Tag.least_used
ActsAsTaggableOn::Tag.least_used(3)

# RockのタグがつけられているLiveHouseを取得する
live_house = LiveHouse.tagged_with("Rock")

# RockとMetalタグがつけれれているPostを取得する
# :match_all (AND条件), :any (OR条件), :exclued (NOT条件)が使える
model = LiveHouse.tagged_with(["Rock", "Metal"], match_all: true)

# 同じタグを持ったレコードを検索する
model.find_related_skill #=> [<Post ...>, <Post ...>]

Veiw側の設定

%= form_for(@user) do |f| %>
  ...
  <div class="field">
    <%= f.label :name, "名前" %><br>
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :tag_list, "タグ(カンマ区切り)" %><br>
    <%= text_field_tag 'user[tag_list]', @user.tag_list.join(',') %>
  </div>

コントローラーは、StrongParameterで入力されたタグを取得する。

# app/controllers/users_controller.rb
def user_params
  params.require(:user).permit(:name, :tag_list)
end

ユーザのタグ登録を楽にするには

QiitaとかWontedlyに良くある、タグに×ボタンがついてるやつ。
以下の外部ライブラリのどちらかで対応できそう。

github.com

github.com

その他細かい部分は以下の記事を参照。

ruby-rails.hatenadiary.com 9bar.tokyo