0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Rails】ransackを使用した検索機能の作成

Posted at

Railsにてransackというgemを使用して投稿一覧にて検索機能を作成。備忘録として記述。

検索機能を使わない場合は公開中の全投稿を表示、検索機能を使用した場合は検索結果を表示していきます。
フォロー機能も実装しているので、今回は、「都道府県」「ジャンル」「フォローしている人かどうか」で検索できるようにしていきます。

※新規投稿する際に都道府県、ジャンル、投稿の公開・非公開を選択して投稿する仕様にしています。(都道府県、ジャンル、投稿の公開・非公開はenumにて管理)

・都道府県

  enum prefecture: {
                    hokkaido: 0,
                    aomori: 1,
       ~~~~~~~~~~~~    省略     ~~~~~~~~~
                    kagoshima: 45,
                    okinawa: 46,
  }

・ジャンル

enum location_genre: { food: 0, location: 1 }

・投稿の公開・非公開

enum released_flag: { released: 0, not_released: 1 }

①ransackのインストール
Gemfileに下記記述。

gem 'ransack'

インストールする。

bundle install

②コントローラーにメソッド記述。

 def index
    if params[:follow].present?
      @follow = params[:follow]
    else
      @follow = false
    end

    @q = Post.ransack(params[:q])
    @user = current_user.followings
    @posts = @q.result(distinct: true).released.order(created_at: :desc).page(params[:page])

    if @follow == 'true'
      @posts = @q.result(distinct: true).where(user: @user).released.order(created_at: :desc).page(params[:page])
    end
  end

順を追って解説していくと、
(1)下記の記述については、もしパラメーターにfollowが存在していれば@followにパラメーターのfollowを定義。
もし存在していなければfalseを定義。

if params[:follow].present?
  @follow = params[:follow]
else
  @follow = false
end

(2)下記の記述については、
@q→Postの中から検索した情報をパラメーター(:q)に入れる。
@user→現在ログインしているユーザーがフォローしている人を定義。
@posts→@qの中から公開中(released)のものを検索して表示。(公開中の投稿を全表示)
distinct: true→重複を削除。
order(created_at: desc)→投稿を降順に表示。

@q = Post.ransack(params[:q])
@user = current_user.followings
@posts = @q.result(distinct: true).released.order(created_at: :desc)

(3)下記の記述については、
①で定義した@followがtrueの場合に、ログインユーザーがフォローしている人(current_user.id.followings)かつ公開中(released)の投稿を表示。

if @follow == 'true'
  @posts = @q.result(distinct: true).where(user: @user).released.order(created_at: :desc)
end

③モデルに記述。
「検索可能な列」や「検索可能な関連モデル」をモデル内に予め定義しておく必要がある。
※悪意のあるユーザーが任意の検索条件を実行して、内部データを推測するセキュリティ問題を回避するため

def self.ransackable_attributes(auth_object = nil)
    ["address", "created_at", "id", "latitude", "location_genre", "location_name", "longitude","memo", "prefecture", "updated_at", "user_id"]
end

def self.ransackable_associations(auth_object = nil)
    ["favorites", "image_attachment", "image_blob", "notifications", "user"]
end


④viewに記述
フォロー済みユーザーを検索するかどうかは、チェックボックスへのチェックの有無にて判断するように実装。
検索ボタンは画像にて表示できるようにしました。

<%= search_form_for @q, url: posts_path, id: 'search_form' do |f| %>
  <%= f.select :prefecture_eq, Post.prefectures_i18n.invert.map{|key, value| [key, Post.prefectures[value]]},
                      { include_blank: t('--都道府県--') } %>
 <%= f.select :location_genre_eq, Post.location_genres_i18n.invert.map{|key, value| [key, Post.location_genres[value]]},
                      { include_blank: t('--ジャンル--') } %>
 <%= label :follow, "フォロー済みユーザー" %>
 <%= check_box_tag :follow, true, @follow %>

  <%= image_submit_tag('検索ボタンの画像', width: "75px", height: "auto", class: "mx-1") %>
<% end %>
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?