Madogiwa Blog

主に技術系の学習メモに使っていきます。

RubyonRails:form_tagを使って入力値がリセットされない検索フォームを作る

Railsでフォームを作る際にform_forを使うとページの再描画が発生しても入力値がリセットされませんが、form_tagを使うとリセットされてしまいます。。。

f:id:madogiwa0124:20180504220013g:plain

検索フォーム等では、form_tagを使用することが多いような気がするのですが、検索ボタンを押してもリセットされずに残ってほしいなー!と思い対応してみたので、その方法をメモしておきますφ(..)

入力値がリセットされない検索フォームの作り方メモ

今回は、indexアクションでは全件取得、searchアクションでは検索条件に合致したレコードを取得して、最終的に共通なViewを描画するようなケースを想定してます。

Controller側

controller側のポイントは、prepare_search_attrです。
indexの場合はパラメーターが無いケースがあるので、検索条件を保持するインスタンス変数@search_attrに初期値を入れておき、検索条件が設定されていた場合は、それを上書きするようにしています。

controller

class TasksController < ApplicationController
  def index
    prepare_search_attr
    @tasks = Task.all
  end

  def search
    prepare_search_attr
    @tasks = Task.search(@search_attr)
    render :index
  end

  private

  def prepare_search_attr
    @search_attr = { title: '', status: '' }
    @search_attr = task_params.delete_if { |_key, val| val.blank? } if params.key?(:task)
  end

  def task_params
    params.require(:task).permit(:title, :description, :status, :priority, :deadline)
  end
end

View側

view側のポイントは_search_form.html.hamltext_field_tagselect_tagを記載しているところです。
text_field_tagは第二引数に渡された値が初期値として設定され、select_tagoptions_for_selectの第二引数に渡された値が初期値として設定されます。

そのため、controller側で定義しておいた@search_attrを、渡して初期値を設定することが出来ます。

index.html.haml

%h1= t '.title'
= render partial: 'search_form', locals: { search_attr: @search_attr }
%br
%table{ border: 1 }
  %thead
    %tr
      %th= Task.human_attribute_name(:title)
      %th= Task.human_attribute_name(:status)
      %th= Task.human_attribute_name(:priority)
      %th= Task.human_attribute_name(:deadline)
      %th Actions

_search_form.html.haml

%div
  = form_tag(search_tasks_path, method: :get) do
    = label_tag :task_title, Task.human_attribute_name(:title)
    = text_field_tag 'task[title]', search_attr[:title]
    = label_tag :task_status, Task.human_attribute_name(:status)
    - statuses = Task.statuses_i18n.invert
    = select_tag 'task[status]', options_for_select(statuses, search_attr[:status]), prompt: '-'
    = submit_tag t('common.search')

おわりに

Railsの検索フォームの作り方は、毎度悩んでこれで良いのかなぁ感が大きいですね・・・(._.)もっと良い作り方等があれば、教えてください!!🙌

またコードの全文は万葉さんの公開している新人研修をやっている私のリポジトリにあるので見てアドバイスもらえるとありがたいですm( )m

github.com

参考

qiita.com

text_field - リファレンス - - Railsドキュメント

select_tag - リファレンス - - Railsドキュメント