dev/mom0tomo

技術メモ

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など他の条件で絞り込みを行いたくなったときに拡張しやすい。