1. はじめに
検索機能を実装する課題があったのでまとめます。
調べたところransackというgemを使っても検索機能を実装できるようですが、課題の趣旨から外れてしまうため、今回はgemなしで実装しました。
#2. Railsで検索機能を実装する[View]
①まずroutesを追加する
コントローラーとモデルは既に作成済みを想定します。
get 'search', to: 'XXX#search'
私の場合は/search
というURLにsearchというcontrollerのアクションを対応させました。
②Viewにform_withで値を設定する
<%= form_with(scope: :検索対象のモデル名, url: search_path, method: 'get') do |form| %>
・・・
・・・
<% end %>
・scope
にはmodel名を指定します。
・urlにはroutes
で指定したcontroller
のアクションを指定します。
・Railsの推奨でmethods
はget
になります。
<%= form_with(scope: :movie, url: search_path, method: 'get') do |form| %>
<div class="search">
<%= form.text_field :search %>
<%= form.submit "検索する" %>
</div>
<% end %>
後はいつも通りform
を実装するように値を入れていきます。
:search
にはユーザーが検索する際のワードが入ります。
③絞り込み機能でラジオボタンを実装する
<%= form_with(scope: :paramsで使用する値, url: search_path, method: 'get') do |form| %>
<div class="radio_button">
<%= form.label :search_radio,"1", value: 1 %>
<%= form.radio_button :search_radio, 1 %>
</div>
<div class="radio_button">
<%= form.label :search_radio,"0", value: 0 %>
<%= form.radio_button :search_radio, 0 %>
</div>
<% end %>
・valueを設定して文字列をクリックしても結果が反映されるように調整
・:search_radio
でcontroller
に値を送信
2.Railsで検索機能を実装する[Controller]
def search
@任意のインスタンス変数 = モデル名.search(search_params)
end
def search_params
params.require(:scopeで設定した値).permit(:search,:search_radio)
end
・モデル名.search(search_params)
ではモデルに定義してあるsearch
メソッドを使用して検索を行います。コントローラーで全て済ませることもできますが、ここは好みだと思います。調べたところ、処理方法は主に3つあるようです。
- コントローラーで全て処理する
- モデルで処理する
- 新しくモデルを作成してそちらで処理する
コントローラーは肥大化させないという考え方もあるようですし、一般的にはモデルで処理するのではないでしょうか。
・任意のインスタンス変数
に先程のモデル名.search(search_params)
を代入してViewで展開できるようにします。
・search_params
ではView
で設定した値を取得しています。この値はモデルに渡されます。
3.Railsで検索機能を実装する[model]
def self.search(search_params)
@任意のインスタンス変数 = モデル名.where( '検索対象カラム名 LIKE ?', "%#{search_params[:search_radio]}%" )
@任意のインスタンス変数.where( '対象カラム名 LIKE ?', "%#{ search_params[:search] }%" )
end
・def self.search(search_params)
では設定したパラメーターを受け取っています。
・@任意のインスタンス変数 = モデル名.where( '検索対象カラム名 LIKE ?', "%#{search_params[:search_radio]}%" )
はラジオボタンの0又は1を検索しています。それをインスタンス変数に代入しています。
・ @任意のインスタンス変数.where( '対象カラム名 LIKE ?', "%#{ search_params[:search] }%" )
では0又は1が入ったインスタンス変数の中でキーワードを検索しています。
modelでの検索をまとめると
1, パラメーターを受け取る
2, 0又は1(true又はfalse)の結果を変数に代入
3, 0又は1の中でユーザーが入力すたキーワードを検索
#5. おわりに
キーワードとラジオボタンを使用した検索方法を実装するのには苦労しました。最初は条件分岐でキーワードがある場合、ない場合を書かなければいけないのかと思っていましたが、最初にtrue又はfalseを代入してからキーワードで検索する方法は目から鱗でした。いい勉強になりました。