実装内容
-
投稿された記事をタグ検索できるようにしよう! というのが主な目的。
-
gemの
acts-as-taggable-on
を使って、記事を投稿する際にタグもDBに保存する。
(今回はサジェスト機能実装がメインなので詳細は割愛。タグ機能実装については
Rails | acts-as-taggable-on を使ったタグ機能の実装 | 備忘録と
[Railsのタグ機能の実装(gem:acts-as-taggable-on)]
(https://www.blograils.com/posts/rails-actsastag)を参考にしました) -
jQuery UIを使ってDBに保存しているタグをもとにサジェスト機能を作成。
開発環境
- Ruby 2.5.1
- Rails 5.2.3
- Haml・Sass記法
実装手順
gemのインストール
gem 'acts-as-taggable-on', github: 'mbleigh/acts-as-taggable-on', branch: 'master'
gem 'jquery-ui-rails'
gem 'jquery-rails'
記述が終わったら、ターミナルでbundle install
も!!
application.jsに追記
//= require jquery
//= require jquery-ui/widgets/autocomplete
jQueryを使えるようにします。
application.scssに追記
@import "jquery-ui/autocomplete";
@import "jquery-ui/theme";
@import "jquery-ui/menu";
今回はSCSSですが、CSSだと*= require jquery-ui
という一文になるそうです。
routes.rbに追記
Rails.application.routes.draw do
root 'reviews#index'
resources :reviews do
collection do
get 'search'
get 'autocomplete' # この1行を追記
end
end
end
この記述をすることによって、以下のようにルーティングが設定できました。
controller.rbに追記
def search
@tags = Review.tagged_with([params[:search_tag]]).order("created_at DESC").page(params[:page]).per(5)
end
# 以下のactionを追記
def autocomplete
all_tags = Review.tag_counts_on(:tags) #全てのタグを取得
tags_name = all_tags.where('name LIKE(?)', "#{params[:term]}%").pluck(:name) #tagsテーブルのnameカラムを前方一致で取得
render json: tags_name.to_json #前方一致で取得した値をjsonにする
end
acts-as-taggable-onをインストールすることで使えるtag_counts_on(:tags)
のメソッドを利用します。このメソッドを使うことで、DBに保存されているタグの値を全て取得することができます。
pluck(:name)
の記述がない状態で、ローカル環境のlocalhost:3000/reviews/autocompleteにアクセスすると、今まで登録したタグが下の画像のように配列でズラリと並んでいる感じになります。
このページに表示されている配列の値が、今後のサジェストにおけるソースになるわけですが、上の配列の状態のままだとサジェストがうまく機能しません。そのため、pluckメソッドを使ってnameカラムを指定し、nameの値だけを取得します。そうすると以下のような配列になります。
JavaScriptファイルを作成
assets配下のjavascriptフォルダにsearch.jsファイルを作成します。
$(document).on('turbolinks:load', function(){
$(".field").autocomplete({
source: "/reviews/autocomplete", //サジェストで表示させる値の取得先
autoFocus: true, //取得した値(サジェストの候補)に自動でフォーカスする
minLength: 1 //1文字入力すればサジェスト機能が動くようにする
})
});
'turbolinks:load'
がないとサジェスト機能がうまく機能しなかった(一度リロードしないと機能しない)ため記述してみました。これで一応問題なく動きます。
適当な入力フォームを作成
あとは下のような入力フォームを作成してあげればいいだけです。
%h2
タグで検索する
.search__form
= form_with model: @review, url: search_reviews_path, method: 'get', local: true do |f|
= f.search_field :search_tag, class: 'field', placeholder: "タグを入力してください"
= f.submit 'Search', class: 'search-btn'
ポイントは= f.search_field :search_tag, class: 'field'
の部分です。
先ほど作成したJavaScriptファイルでは、field
というクラスが適用されたフォームで文字の入力があった際に発火するようにしたので、クラス名が違っていると動かないので要確認です。
以上で、簡易的なサジェスト機能の完成です。
終わりに
折角タグ機能を実装したのだから、ちゃんと生かせるようにしよう!と思い実装に着手したサジェスト機能でした。簡易的でしたが、思った以上に実装は簡単でした!今後は、より高度な実装に着手していきたいです。
参考記事一覧
Rails | acts-as-taggable-on を使ったタグ機能の実装 | 備忘録
[Railsのタグ機能の実装(gem:acts-as-taggable-on)]
(https://www.blograils.com/posts/rails-actsastag)
[railsでサジェスト機能を実装してみた]
(https://qiita.com/anuma/items/c76de8d009266491fba1)
[Rails】JQuery UI オートコンプリートを実装してみました【Javascript】]
(https://vastworld.org/code/925)