一覧画面で検索機能を実装するにあたって、Ransackを使うと
どんな感じになるのか気になったので、実装してみました!
前提として、投稿機能の実装が必要ですが、その点は省略しています
導入
まず、Gemfileを編集します。
Gemfile
gem 'ransack'
次に、以下のコマンドを実行します。
ターミナル
bundle install
ルーティング
routes.rb
Rails.application.routes.draw do
resources :posts do
collection do
get 'search' => 'posts#index'
end
end
root 'posts#index'
end
今回は一覧画面での実装としているため、検索時に
posts#index
を指定しています。
Viewの編集
index.html.erb
<div>
<h2>検索</h2>
<%= search_form_for @q, url: search_posts_path do |f| %>
<%= f.label :body_cont, '投稿内容' %>
<%= f.search_field :body_cont %>
<br>
<%= f.submit '検索' %>
<% end %>
</div>
検索したいカラムの指定はカラム_cont
とする必要があります。
また、フォーム実行時のURLはrails routes
で確認したパスを入れましょう!
Ransack自体の詳しい解説は以下の記事が参考になります。
Controllerの編集
posts_controller.rb
class PostsController < ApplicationController
before_action :set_post, only: %i[ show edit update destroy ]
+ before_action :set_q, only: [:index, :search]
# GET /posts or /posts.json
def index
- @posts = Post.all
+ if @q
+ @posts = @q.result
+ else
+ @posts = Post.all
+ end
end
# ~~~~~特に変更がないので省略~~~~~
private
+ def set_q
+ @q = Post.ransack(params[:q])
+ end
# Use callbacks to share common setup or constraints between actions.
def set_post
@post = Post.find(params[:id])
end
# Only allow a list of trusted parameters through.
def post_params
params.require(:post).permit(:body, :image, :user_id)
end
end
before_action :set_q, only: [:index, :search]
検索、一覧画面の時に検索の情報を取得したいので設定しています。
また、以下の部分では、検索時の情報がある場合は検索した投稿をViewに渡すように
条件分岐を実装しています。
posts_controller.rb
@posts = Post.all
if @q
@posts = @q.result
else
@posts = Post.all
end
最後に
頑張って検索を実装するよりRansackを使った方が楽な実装だと
個人的には感じたので、今後はRansackを使っていきます!!笑
読んでいただきありがとうございました!
参考文献