とまとの成長日記

ぴよぴよエンジニアの日々学んだとこを投稿。時々、ゆるーくすきなもの・趣味について語ってます。

gem ransack 使ってみた

railsには便利なgemがたくさんあってransack(ランサック)もその中の一つです。
gem ransack はrails用の検索機能です。
結構簡単に実装できます!
初心者でもできちゃったので一緒にやっていきましょう!
今回は掲示板の一覧のページで掲示板のタイトルから検索するようにします。

※distinct: trueに関して誤りがあるかもなので確認中です。
→内容少し変更しました!
→更に追記しました!(2019/07/10)

Gemfileに追加
gem 'ransack'

インストールします

bundle install
Controllerに追加
def index
  @q = Board.ransack(params[:q])
  @boards = @q.result(distinct: true)
end

def search
    @q = Board.ransack(params[:q])
    @boards = @q.result(distinct: true)
  end

今回は掲示板一覧画面に検索フォームをつけるのでindexと
検索結果を示すsearchアクションを定義します。

@q = 検索したいモデル名.ransack(params[:q])
@モデル名s = @q.result(distinct: true)

この2つをそれぞれに定義しましょう!
distinct: true は、
例えば、検索するものが掲示板タイトルと、掲示板コメントから探してくるとします。
とまとという内容のワードが同じ掲示板タイトルと、掲示板コメントにあった場合、重複して結果を表示してしまいます。
重複を避けるために使うのが、distinct: true になります!

↑の説明は、ずれているので無視してください。
ざっくりとした認識で distinct: true は、重複したデータを除外したものになります!
詳しくはこちらを参考にしていただければと思います!
重複したデータを除外してデータを取得する(DISTINCT) | MySQLの使い方

追記
例えば、画像にコメントができるようになっていたとします。(画像対コメントが1対多になっていたとする)
この時、コメントを検索する時に画像が一覧で表示されるようになっていたとします。
同じ画像に同じワードを使ったコメントがあった場合、distinct: true がない場合同じ画像が2つ表示されてしまいます。
distinct: true を使っていれば、重複を削除しているので画像は1つのみの表示になります!
※最初の説明との違いは、テーブル設計を無視した説明になっているので誤りです。

f:id:toomeeto:20190710145432j:plain
検索前イメージ

f:id:toomeeto:20190710145435j:plain
検索後イメージ

Routesに追加
get 'search', to: 'boards#search'

これで検索結果を表示するルーティングの設定は完了です!
これは、さっき作った、searchアクションをルーティングに作っています。

Viewに追加

まずは掲示板一覧に検索フォームを追加しましょう。

<%= search_form_for @q, url:search_path do |f| %>
   <%= f.text_field :title_cont %>
   <%= f.submit '検索' %>
<% end %>

ざっくり解説するとこんな感じ
search_form_for のあとの引数に @q, url:ルーティング

OO_contで検索したい内容をOOに入れる。
もし、検索したいものが複数あれば、
OO_cont_or_OO_cont

また、OO_contはOOを含むという意味で
OO_eqでOOと全く同じという検索方法もあります。
公式にいろんな検索条件の指定方法が載っているので気になる人は見てください!



なんと!!これで検索機能ができちゃいます!!!
正直仕組み的なのはわかってないところが多いですが、
でも動くので良しとしましょう。笑

追記
現役エンジニアの方のお話によると…
ransackはフロントサイドとサーバーサイドが密接に関わってしまうので、より高度なコードを書く場合は避けて使うこともあるそうです!
どのgemを選択するかというのはエンジニアの様々な考え方があるので面白いですね😆

参考資料
github.com

qiita.com

感想

意外と簡単に検索機能が作れたのでちょっとテンション上がりました🤩🤩
そして、眠気に負ける日々が続いて甘えが出ております。
土日は昼から活動して、ちゃんとその日中には出せるようにがんばるぞー!