#行ったこと
Railsチュートリアル6.0を完走し、最後に拡張機能としてユーザー検索を実装した
自分の勉強のためにアウトプットしています。
#完成版はこちら
https://damp-spire-94870.herokuapp.com/users?search=e&commit=%E6%A4%9C%E7%B4%A2
#参考記事
https://qiita.com/mochikichi321/items/5c9630c5d87b47130942
https://qiita.com/s-yank/items/964e82bcecaa659caa2d
#手順(チュートリアル14章まで終わっていることが前提)
##1現時点のコード確認
<% provide(:title, 'All users') %>
<h1>All users</h1>
<%= will_paginate %>
#ここへ検索拡張機能追加予定
<ul class="users">
<%= render @users %>
</ul>
<%= will_paginate %>
class UsersController < ApplicationController
(中略)
def index
@users = User.where(activated: true,).paginate(page: params[:page])
#activatedがtrueの物だけ探して、paginateしている
end
(中略)
end
##2まずは、ビューを整える
<% provide(:title, 'All users') %>
<h1>All users</h1>
<%= will_paginate %>
#検索窓
<%= form_with(url:users_path, :method => 'get',local: true) do |form| %>
<%= form.label :ユーザー検索 %>
<%= form.text_field :search,class:'form-control' %>
<%= form.submit '検索' , class: "btn btn-primary" %>
<% end %>
<ul class="users">
<%= render @users %>
</ul>
<%= will_paginate %>
ここでつまずいたので解説すると、
<%= form_with(url:users_path, :method => 'get',local: true) do |form| %>
<%= form.label :ユーザー検索 %>
<%= form.text_field :search,class:'form-control' %>
<%= form.submit '検索' , class: "btn btn-primary" %>
<% end %>
form_withはform_tagが非推奨になったことから、railsチュートリアルでも利用していたタグ。
url
,method
、local
を指定する。
method => 'get'
を指定しないと、form_withがデフォルトでmethod post送信なのでうまく処理されないらしい
local:true
を指定しないと、form_withがデフォルトでremote: trueとなり、送信したデータがAjax通信で処理されます
その場合、検索ボタンを押した時に画面が遷移しないため、indexの一覧画面の情報が更新されなくなってしまう。
classの指定はbootstrapを反映させるためです。
##3コントローラー側
コントローラー側はこちらの記事を参考(マルパクリ)で
https://qiita.com/mochikichi321/items/5c9630c5d87b47130942
class UsersController < ApplicationController
(中略)
def index
#条件分岐
@users = if params[:search]
#searchされた場合は、原文+.where('name LIKE ?', "%#{params[:search]}%")を実行
User.where(activated: true).paginate(page: params[:page]).where('name LIKE ?', "%#{params[:search]}%")
else
#searchされていない場合は、原文そのまま
User.where(activated: true).paginate(page: params[:page])
end
end
(中略)
end
こうなります
where('name LIKE ?', "%#{params[:search]}%")
の部分は、SQLの文法で
https://techacademy.jp/magazine/22330
を参考にすると
User.where("name LIKE ?", "%hana%")
LIKE句はSQLの検索を行うための演算子
name LIKEと書くことでnameカラムを検索、という意味になる
?は次の引数"%hana%"を受け取る場所になります。最終的にname LIKE "%hana%"という風になるということです。%は任意の文字列を指します。
つまり、nameカラムにhanaを含むレコードを抽出する、という処理になるらしい。
最終的に、
where('name LIKE ?', "%#{params[:search]}%")
params[:search]で受け取った文字式展開を受け取り、検索すると言う事になります。
これで実装されるはずですがリファクタリングもしておきます。
##4リファクタリング
class User < ApplicationRecord
(中略)
def self.search(search) #ここでのself.はUser.を意味する
if search
where(['name LIKE ?', "%#{search}%"]) #検索とnameの部分一致を表示。#User.は省略
else
all #全て表示。#User.は省略
end
end
private
(中略)
end
class UsersController < ApplicationController
(中略)
def index
@users = User.where(activated: true).paginate(page: params[:page]).search(params[:search])
end
(中略)
end
これでform_withを使った検索の実装は終わりです
後日、こちらのテストも書いてみたいと思います。