ransackを使って検索機能を実装します。

まず最初にGemfileransackを追加して、bundle installします。

gem 'ransack'

ユーザーコントローラのindexアクションに検索できるような設定を行います。

def index
  @q = User.ransack(params[:q])
  @users = @q.result(distinct: true)
end

ユーザー検索機能をつけるusers/index.html.erbファイルに検索機能をつけました。

<% content_for(:title, 'User search') %>

<p id="notice"><%= notice %></p>

<h1>search</h1>

<%= search_form_for @q do |f| %>
  <%= f.search_field :name_cont, placeholder: 'user name' %>
  <%= f.submit class: 'btn btn-primary' %>
<% end %>

<table class="table table-sm col-12">
  <thead class="thead-light">
    <tr>
      <th class="text-center">nickname</th>
      <th class="text-center">name</th>
      <th colspan="5"></th>
    </tr>
  </thead>

  <tbody>
    <% @users.each do |user| %>
      <tr>
        <td class="text-center"><%= link_to user.nickname, user_diaries_path(user) %></td>
        <td class="text-center"><%= user.name %></td>
        <td class="text-center"><% if logged_in? && current_user != user %>
          <% if current_user.following?(user) %>
            <%= render 'relationships/unfollow_button', user: user %>
          <% else %>
            <%= render 'relationships/follow_button', user: user %>
          <% end %>
        <% end %></td>
      </tr>
    <% end %>
  </tbody>
</table>

ユーザー一覧の上に検索フォームが作成されました。しかし私は検索フォームで入力した後に、その検索条件に一致するユーザー情報だけ表示させたかったので、少しだけ変更していこうと思います。

まず最初に検索するページと検索結果が表示されるページの二つのページが必要になるので、usersアクションにもう一つアクションを追加します。

class UsersController < ApplicationController
	def index
    @q = User.ransack(params[:q])
  end

	def search
    @q = User.search(params[:q])
    @users = @q.result(distinct: true)
  end
end

ルーティングも追加します。

get 'search', to: 'users#search'

検索結果を表示するビューファイルを作成します。

Sayo-MacBook-Pro:emoji_diary SAYO$ touch app/views/users/search.html.erb