はじめに
今回はacts-as-taggable-onというgemを使用しました。
その実装過程を残します。
導入
gem 'acts-as-taggable-on'
bundle installするとマイグレーションファイルがいくつか自動生成されるので、
次にrails db:migrateを行うとエラーが出ます。
Mysql2::Error: Cannot drop index 'index_taggings_on_tag_id': needed in a foreign key constraint: DROP INDEX `index_taggings_on_tag_id` ON `taggings`
ActiveRecord::StatementInvalid: Mysql2::Error: Cannot drop index 'index_taggings_on_tag_id': needed in a foreign key constraint: DROP INDEX `index_taggings_on_tag_id` ON `taggings`
調べるとこれはgem自体の問題で、作成者が修正してない状態なのだとか。
ざっくり概要としては外部キーを設定しているにも関わらず、外部キーを削除せずにインデックスを削除しようとしているためエラーが出ているようです。
GitHubのissuesに不具合報告に修正案がありました。
remove_index ActsAsTaggableOn.taggings_table, :tag_id if index_exists?(ActsAsTaggableOn.taggings_table, :tag_id) #削除
if index_exists?(ActsAsTaggableOn.taggings_table, :tag_id) #追加
remove_foreign_key :taggings, :tags #追加
remove_index ActsAsTaggableOn.taggings_table, :tag_id #追加
end #追加
これで通ったと思いきや今度はArgumentErrorが出ます。
しかしこれは一度目のmigrate実行時に最初のファイルだけ読み込んでいたからのようです。
全てrollbackをして、再度migrateを実行するとついに導入完了しました。
正直ここが一番時間かかった...笑
モデル
続いてアソシエーションです。
acts_as_taggable # acts_as_taggable_on :tags の省略
コントローラー
ここでは2点。
1・登録のためにストロングパラメーターに追加
2・表示のために紐づくものを取得
def show
@room = Room.find(params[:id])
@tags = @room.tag_counts_on(:tags) #追加
end
private
def room_params
params.require(:room).permit(:title, :psid, :tag_list, :member_id, :text).merge(user_id: current_user.id) #追加
end
tag_counts_onはgemに備わっているメソッドで、タグ一覧を取得できます。
今回はアソシエーションで@roomに紐づくタグを取得しています。
ビュー
, (デフォルト)で区切ると、複数タグに分割してくれる。
<%= form.text_field :tag_list, value: @room.tag_list.join(',') %>
tag_listは配列なので、each文で取り出して表示する。
<% @tags.each do |tag| %>
<%= "#{tag.name}(#{tag.taggings_count})" %>
<% end %>
さいごに
今後はUIを整えたり、検索機能なども実装したいと思います。
普段何気なく使っている機能も、
いざ自分でやると大変なんだと常々思い知らされます...