検索機能の実装

今回は検索機能についての紹介します。 今回のコードはこちらです。 post.controller.rb

 def search
    if params[:keyword].present?
      @posts = Post.search(params[:keyword]).page(params[:page]).per(6)
      if @posts.length == 0
        flash.now[:alert] = '検索した内容は見つかりませんでした'
        @posts = Post.includes(:game, :grade, :user).page(params[:page]).per(6)
      else
        flash.now[:notice] = '検索した内容は見つかりました'
      end
    else
      flash[:alert] = '検索した内容が空白です'
      redirect_to root_path
    end
  end

post.rb(モデル)

def self.search(search)
    if search != ""
      Post.where('title LIKE(?)', "%#{search}%")
    else
      Post.includes(:game, :grade, :user)
    end
  end

まず検索の流れについてです。

  if params[:keyword].present?
      @posts = Post.search(params[:keyword]).page(params[:page]).per(6)
#中略
  else
      flash[:alert] = '検索した内容が空白です'
      redirect_to root_path
  end

この部分で空欄になるかどうかを判定します。 これをすることで、空欄場合は一覧機能(root_path)に遷移して、flashで空白であることを通知して、検索機能を機能させない様にすることができます。一応万が一この機能を突破された場合は、一覧を表示するようにモデルに記述しています。 次に検索ワードが入っている場合です。

      if @posts.length == 0
        flash.now[:alert] = '検索した内容は見つかりませんでした'
        @posts = Post.includes(:game, :grade, :user).page(params[:page]).per(6)
      else
        flash.now[:notice] = '検索した内容は見つかりました'
      end

@postsにデータが入っているかどうかを識別し、データベースからキーワードにあった情報を抜き取れなかった場合には、@postsには何もない状態となってしまうため、 @postsに一覧を再代入して、何かしらの動画を表示する様にしています。

追伸

ちなみに.page(params[:page]).per(6)はkaminariというページネーション機能を用いるためのgemになります。 個人的には@postsに当たる部分をhtml.erbで@postのように違う変数を作るべきかどうか非常に迷いましたが、再代入すれば問題なく再利用できるということに気づき、新しい発見をすることができました。 通常の場合何かしら検索にヒットする可能性が高いため、見つけた場合を上に持ってくるべきだと考える人もいるかもしれませんが、現状自分しか投稿予定がないため、ヒットしない方を前提に見つからないを上に持ってきています。