form_withを使って検索フォームをつくる
form_withを使ってこんな検索フォームを作った。
user/index.html.slim
= form_with model: User.new do |form| = form.label :name, '名前' = form.text_field :name, value: (params[:user][:name] if params[:user]) = form.submit '検索する'
users_controller.rb
class UserController < ApplicationController def index @users = query.order(:id).page(params[:page]) end private def query if params[:user].present? && params[:user][:name] User.where('LOWER(name) LIKE ?', "%#{params[:user][:name].downcase}%") else User.all end end end
検索フォームによくある下記の様な要件を実装しているのでちょっと複雑に見える。
- 検索した文字列を検索した後もフォームに残す (
value: (params[:user][:name] if params[:user])
) - 大文字小文字を区別せずに検索する (
LOWER() 〜 .downcase
) - 検索結果をID順に並べる (
.order(:id)
) - kaminariを使ってページネーションする (
.page(params[:page])
)
この条件を外してシンプルにしてみる。
user/index.html.slim
= form_with model: User.new do |form| = form.label :name, '名前' = form.text_field :name = form.submit '検索する'
users_controller.rb
class UserController < ApplicationController def index @users = query end private def query if params[:user].present? && params[:user][:name] User.where('name LIKE ?', "%#{params[:user][:name]}%") else User.all end end end
こうしてシンプルにしてみるとわかりやすい。
form_withのポイントは、
user/index.html.slim
= form_with model: User.new, method: :get do |form| = form.text_field :name
このようなフォームのパラメータは params[:user][:name]
という形で取得できること(controller参照)。
また、検索フォームとしてのポイントはコントローラの中での検索処理をqueryメソッドに切り出していること。
こうしておくとUserのIDやemailなど他の条件で絞り込みを行いたくなったときに拡張しやすい。