19
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Rails】ヘッダーへの検索機能の付け方

Last updated at Posted at 2019-03-21

「検索機能をつけたい!」
「検索ページを作るのではなく、検索窓として常にアプリ上部に出てくるようにしたい!」
といった時の対応方法です。

↓参考イメージ(Qiitaでいうこんな部分)
スクリーンショット 2019-03-21 11.51.42.png

#はじめに
今回の前提は、

  • 検索対象モデルがある。(今回はproductモデルと仮定する)
  • 検索対象モデルのindexページがある。(例:app/view/products/index.html.erb)
  • indexページを再利用して検索結果を表示させる。

としたいと思います。

#元コードイメージ

コントローラ

app/controllers/products_controller.rb
def index
  @products = Product.all
end

view

app/view/products/index.html.erb
<% render partial: 'products/product', collection: @products %>

collectionを使って各商品を表示させてます。

app/view/products/_product.html.erb
<%= product.name %>
<%= product.price %>

パーシャルを用いて各productの情報を表示させていきます。
※パーシャル名=変数名となるので注意。(例:_user.html.erbの場合は、user.nameとなる。)

だいたいこんな感じの状態のものを想定します。

#①Gemインストール
今回はransackというgemを使用します。

Gemfile
gem 'ransack'

記述したらbundle installする。

#②検索機能の追加(コントローラの修正)
実は今回products_controller.rbは触りません。
products_controller.rbで検索機能を追加すると、検索”窓”として、どのページからでも使用することはできなくなるからです。
そのためapplication_controller.rbに機能追加していきます。

app/controllers/application_controller.rb
before_action :set_search

def set_search
  @search = Product.ransack(params[:q])
  @search_products = @search.result
end

#③検索窓の作成(viewの修正)
検索窓を作っていきます。
今回は特定のviewではなく、検索窓のような形で作成するので、application.html.erbなどに記入しましょう。

app/view/layouts/application.html.erb
<%= search_form_for @search, products_path do |f| %>
  <%= f.text_field :name_cont, placeholder: '名前を入力...' %>
  <%= f.submit ("検索する") %>
<% end %>

ポイントは下記の部分です。

  • search_form_forform_forのRansack版。
  • products_pathの記載によって、リダイレクト先はproductのindexページを指定している。
  • 2行目に書いている:name_contの記載によって、nameカラムに対して部分一致検索ができるようになる。

#④indexページでの条件分け(パーシャルへの変数の出し分け)
indexページを再利用するために、条件指定をします。

  • 「検索窓→indexページ」の時には検索結果を表示させたい。(@search_productsを表示させる。)
  • 上記以外の場合には、全ての商品を表示させたい。(@productsを表示させる。)
app/view/products/index.html.erb
<% if @search_products %>
  <% render partial: 'products/product', collection: @search_products %>
<% else %>
  <% render partial: 'products/product', collection: @products %>
<% end %>

これで、
@search_productsが存在する場合には、@search_productsがパーシャルに渡され、
@search_productsが存在しない場合には、@productsがパーシャルに渡されるので、indexページの再利用ができます。

おわりに

まだまだ駆け出しエンジニアなので、変な部分ありましたらドシドシコメント欲しいです!

19
24
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
19
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?