まだ検索機能の実装に消耗しているの? 一瞬で実装できるGem 'ransack'


こんにちは、

今回は検索機能を爆速で実装できるGem

Ransack

です。


いやーこれはすごい便利ですね。
検索機能ってさりげレベル高くね?
って思っていたのですが、
このGemを使えば30分ほどで実現できます。

改めてGemすげーって感じです。
(語彙力)


では早速やっていきましょう



まずは

gem 'ransack'

をGemfileに入れていきます。

% bundle install

を忘れずに


ルーティング行きます

 resources :books do
    collection do
      get 'search'
    end
  end

ルーティングは

         search_books GET      /books/search(.:format)                                                                  books#search

こんな感じになります。

collectionに似たものにmemberがあるのですが

 member do
      get 'search'
 end

にするとルーティングにidを含めることができます

         search_books GET      /books/:id/search(.:format)                                                                  books#search

今回はbookのデータベースの中にあるtag_nameというカラムを検索できるようにしたいのでこうしました。


次はビューを作ります

rails g controller books  search

こうするとコントローラーとsearchのViewが作れます。


コントローラーコントローラー♪

books_controller.rb
class BooksController < ApplicationController
  before_action :search_book, only: [:index, :search]


  def index
   @books =Book.all

   @book =Book.includes(:user)
   set_book_column 
  end


  def search
    @results = @p.result
    @book = @results.includes(:book)
  end


  private

  def search_book
    @p = Book.ransack(params[:q]) 
  end
  def set_book_column
    @book_name = Book.select("tag_name").distinct 
   end
end

こんな感じです。

Book.select("tag_name").distinct

のtag_nameのところに検索したい要素を入れます



before_action入れると
何よりも早く読み込んでくれます。



次はViewです!

books/index.html.reb
<%= search_form_for @p, url: search_books_path do |f| %>
    <%= f.label :tag_name_cont, 'タグ名' %>
    <%= f.text_field  :tag_name_cont, placeholder: "タグの名前で検索" %>
    <br>
    <%= f.submit '検索' %>
<% end %>

search_form_forメソッドはランサック特有のメソッドです

二行目に書いてあるtag_name_cont のcontは
だいたい合っていれば検索に引っかかる。

というやつです。

eqにすると全く同じやつしか引っかからなくなります。

他にもいくつかあるので見てみてください!
Ransackのススメ


検索結果画面作ります

books/search.html.erb
   <h1 class="search-forms">
     検索結果
   </h1>
<head class ="search-book-list">
  <div class="book-chosen">
  <%# 検索該当商品一覧 %>
   <% if @results.length !=0 %>    
    <% @results.each do |result| %>
     <br>
     <div class="sec1title">
    <div class="item-show">
          <h2 class='border01'>
            <%= result.genre.type %>
             <%= link_to "/books/#{result.id}" do %>
        <%end %>
          </h2>
        <%= image_tag result.image, id: 'slideshow' if result.image.attached? %>
        <div class="item-info" >
          <h2 id ='item-name'>
            <%= result.name %>
          </h2>
            <form class="item-content-show">
            <%= result.content %>
            </form>
        </div>
        <br />
       </div>
     </div>
    <% end %>
   <% else %>
    <br/>
   該当する商品はありません
   <br/>
   <br/>
<div>
   <%=link_to  "ホームへ戻る",root_path%>
</div>
   <% end %>
   <br>
  </div>

<%# ホームボタン %>
   <%= render "shared/sidebar" %>

 </head>

dekita!

コントローラーで

 def search
    @results = @p.result
    @book = @results.includes(:book)
  end

このように表記してるので@resultから
値を取り出していせています。



以上で説明は終わります。
環境 Ruby on rails


何かミスがあれば遠慮なくコメントお願いします!!