Railsでそれらしくタグが作れるgem「acts-as-taggable-on」のご紹介。
今回はタグをオーナーを設定して作る方法を紹介します。オーナーの設定は「ユーザーがお気に入りの記事をタグで分類」みたいなときに使うと便利です。本家のドキュメントにも記載されているのですが、特にtaggingについての説明が不十分と感じたので、その辺を盛り込みながら説明していまきす。
acts-as-taggable-onの登場人物4名
- tag: タグの本体
- taggable: タグの対象(ニコニコ動画であれば動画)
- tagger: タグのオーナー(タグを付けた人)
- tagging: tag, taggable, taggerのリレーションモデル
タグの対象(taggable)の設定。モデルに記載。
class Blog < ActiveRecord::Base
acts_as_taggable #「acts_as_taggable_on :tags」と同じ
end
タグのオーナー(tagger)の設定。モデルに記載。
class User < ActiveRecord::Base
acts_as_tagger
end
タグの作成と削除
タグの作成と削除について共通する点なんですが、公式のドキュメントで紹介されている方法通りに単純に行うと、タグの「追加」ではなく「置き換え」になってしまいます。
@some_user.tag(@some_photo, :with => "paris, normandy", :on => :locations, :skip_save => true)
@some_photo.owner_tags_on(@some_user,:tags) # => ["paris", "normandy"]
@some_user.tag(@some_photo, :with => "練馬", :on => :locations, :skip_save => true)
@some_photo.owner_tags_on(@some_user,:tags) # => ["練馬"]
上のコードだと「練馬」に書き換えられている。
そこで、一度taggerとtaggableと関連付けられたtag_listを呼び出し、addメソッドとremoveメソッドで追加、削除の処理をしたうえで、tagメソッドで状態を保存するという手順を紹介します(tagメソッド内でsaveが呼ばれている)。
つまり、
1.既存のタグリストの取り出し
2.既存のタグリストに新規タグの追加(この時点では保存されていない)
3.「既存タグ+新規タグ」のタグリストを保存
という流れ。
タグの作成手順
タグ本体の作成とリレーション(タグ、対象、オーナー)の構築を目指します。
tag_list = blog.tags_from(user) #一度 ActsAsTaggableOn::TagListを呼ぶ
tag_list.add('hoge')
user.tag(blog, with: tag_list, on: :tags)
タグの削除手順
tag_list = blog.tags_from(user)
tag_list.remove('hoge')
self.tag(blog, with: tag_list, on: :tags)
削除手順で特筆すべきなのは、この手順で行うとtaggingの削除とtaggings_countのデクリメントが行われている点です。単純にリレーションモデルであるtaggingを引っ張って来て削除しても良いのですが、その場合、tagのtaggings_countは反映されません。タグクラウドが多分使えなくなります。
タグの表示(view)
taggerのowner_tags_onメソッドの返り値は「ActiveRecord::AssociationRelation」なので、よくある感じに表示していきます
<% blog.owner_tags_on(current_user, :tags).each do |tag| %>
<%= tag.name %>
<% end %>
タグ(tag, tagging)の取得
ActsAsTaggableOn::Tag.find(:id)
ActsAsTaggableOn::Tagging.find(:id).tag # tagging.tag
blog.tags
blog.taggings #タグではなく、tagging
オーナーの取得
ActsAsTaggableOn::Tagging.find(:id).tagger
tagging.tagger
タグの対象の取得
ActsAsTaggableOn::Tagging.find(:id).taggable
tagging.taggable
以上です。
個人的にオーナーを設定するなら、taggingを取得して操作すると捗ると思います。