Rails初心者が「form_with」を使って検索機能を実装してみた。

##はじめに
Rails5.1から追加された`「form_with」`メソッドを使って、簡易な検索機能を実装してみました。
ある教材で学んだ検索機能の実装手段が、Rails5.1以降で非推奨となる`「form_tag」`を使用していたため、
勉強を兼ねて`「form_with」`で置き換えてみた際に調べたことを纏めます。

##「form_tag」と「form_with」の違いについて
両者の記述方法の違いについては、下記にリンクした投稿記事が大変分かりやすいです。
[【Rails 5】(新) form_with と (旧) form_tag, form_for の違い](https://qiita.com/hmmrjn/items/24f3b8eade206ace17e2)

##検索機能の実装結果
細かい話に入る前に、簡単に検索機能を説明します。
簡単な例として、各地の場所と天気の情報を持ったForecastモデルを作成します。
<img width="403" alt="スクリーンショット 2018-11-16 1.11.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/273275/984dec94-1e48-4371-456e-7c5d02eebde7.png">
検索窓に例えば「sunny」と入力すると、天気が晴れている場所を検索してくれます。
<img width="402" alt="スクリーンショット 2018-11-16 1.21.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/273275/33ee9edb-12e9-00cc-b320-0713c55018a0.png">
##「form_tag」を用いた検索機能の実装例
検索機能の実装部以外は、Railsのscaffold機能で自動生成されたコードです。
簡単に動きを説明すると、「form_tag」で送信先のURL('/forecasts')を指定しています。
また、検索窓の「text_field_tag」に入力されたキーワードは、「weather_key」という名前が付いて、Forecastsコントローラーのindexアクションに送信されます。

```app/views/forecasts/index.html.erb
<p id="notice"><%= notice %></p>

<h1>Forecasts</h1>
<!--ここから先が検索機能の実装部-->
<%= form_tag('/forecasts', method: 'get') do %>
  <%= label_tag(:weather_key, 'Sarch weather') %>
  <%= text_field_tag(:weather_key) %>
  <%= submit_tag('Search') %> <%= link_to 'Clear', forecasts_path %>
<% end %>
<!--ここまで-->

<table>
  <thead>
    <tr>
      <th>Place name</th>
      <th>Weather</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @forecasts.each do |forecast| %>
      <tr>
        <td><%= forecast.place_name %></td>
        <td><%= forecast.weather %></td>
        <td><%= link_to 'Show', forecast %></td>
        <td><%= link_to 'Edit', edit_forecast_path(forecast) %></td>
        <td><%= link_to 'Destroy', forecast, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Forecast', new_forecast_path %>
```
フォームから送信があると、forecastsコントローラーのindexアクションで、キーワードの有無を判定します。
また、キーワード入力があれば、LIKE検索によりDBの情報をソートし、　@forecastas変数に代入します。その後、index.html.erbに抜き出した情報を出力する流れになっています。

```app/controller/forecasts_controller.rb
class ForecastsController < ApplicationController
  def index
    #キーワードが入力されていれば、whereメソッドとLIKE検索（部分一致検索）を組み合わせて、必要な情報のみ取得する。
    if params[:weather_key]
      @forecasts = Forecast.where('weather LIKE ?', "%#{params[:weather_key]}%")
    else
      @forecasts = Forecast.all
    end
  end
end
```
##「form_with」を用いた検索機能の実装例
`「form_tag」`と`「form_with」`との間で大きな違いはありませんが、`「form_with」では「local: true」を指定していることに注意してください。`
「form_with」はデフォルトで、`remote: true`となり、送信したデータがAjax通信で処理されます（XMLHTTPRequest経由でフォームを送信するようです）。その場合、検索ボタンを押した時に画面が遷移しないため、indexの一覧画面の情報が更新されません。そのため、「local: true」を指定して、検索ボタンを押した時に画面が遷移するようにしましょう。

```app/views/forecasts/index.html.erb
<!--ここから先が検索機能の実装部-->
<%= form_with url:'/forecasts', method: :get, local: true do |f| %>
  <%= f.label :weather_key, 'Sarch weather' %>
  <%= f.text_field :weather_key %>
  <%= f.submit 'Search' %> <%= link_to 'Clear', forecasts_path %>
<% end %>
<!--ここまで-->
```
##最後に
Rails5.1以降は「form_with」が正式に標準として使用されるようなので、これからも「form_with」に置き換えた機能実装について投稿していきたいと思います。初心者の投稿ですので、ご指摘等あればコメントして頂ければ幸いです。