LoginSignup
21
33

More than 5 years have passed since last update.

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

Posted at

はじめに

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

「form_tag」と「form_with」の違いについて

両者の記述方法の違いについては、下記にリンクした投稿記事が大変分かりやすいです。
【Rails 5】(新) form_with と (旧) form_tag, form_for の違い

検索機能の実装結果

細かい話に入る前に、簡単に検索機能を説明します。
簡単な例として、各地の場所と天気の情報を持ったForecastモデルを作成します。
スクリーンショット 2018-11-16 1.11.36.png
検索窓に例えば「sunny」と入力すると、天気が晴れている場所を検索してくれます。
スクリーンショット 2018-11-16 1.21.56.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」に置き換えた機能実装について投稿していきたいと思います。初心者の投稿ですので、ご指摘等あればコメントして頂ければ幸いです。

21
33
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
33