#ユーザーを名前で検索する
検索フォームに入力した文字を含む名前をもつユーザーのみを一覧で表示します。
なお、検索フォームに文字が入力されていない場合は全ユーザを表示します。
検索のため、新しくアクションを定義してコントローラーで使用する方法もあります。ですが、可読性やMVCの観点から、Railsの開発はできる限り7つのアクションを利用して開発する方が推奨されている書き方であるため、今回はnamespaceを使用し専用のコントローラを作成する方法で実装します。
以下を使用しています。
- ruby 2.5.1
- rails 5.2.4.1
###namespce(名前空間)
名前の集合を分割すること、または、分割するために付けられる識別名をnamespaceと呼びます。namespaceを用いることで、同様のクラス名を名付けたクラスであってもそれらを区別することができます。
今回の場合、usersディレクトリの配下にsearches_controller.rbを作成し、users::という名前空間が付けられるため、直感的に「ユーザーを検索するコントローラー」ということがわかります。
##実装にあたって
- 今回は前提としてユーザー機能及び、一覧表示は(views/users/index.html.hamlで)出来ている状態から始める
- ユーザーの名前を保存するカラムはnameカラムとする
###userモデルにメソッドを定義
テーブルとのやりとりに関するメソッドはモデルに置きます。
理由として、そのメソッドを別の場所でも使うことができ便利だからです。
def self.search(search)
return User.all unless search
User.where('name LIKE(?)', "%#{search}%")
end
whereメソッドとLIKE句を使用して検索の処理を作ります。
もし、引数で渡されるsearchの中身に何もなければ全ての投稿を取得できるようにしています。
###コントローラーの作成
rails g controller users::searches
上記を実行しコントローラーを作成します。
users:: という名前空間を付けることで、usersディレクトリの配下にsearches_controller.rbを作成できます。
###ルーティングの設定
namespace :users do
resources :searches, only: :index
end
以下が設定されます。
users_searches GET /users/searches(.:format) users/searches#index
このようにnamespace :ディレクトリ名 do ~ endと囲む形でルーティングを記述すると、そのディレクトリ内のコントローラーのアクションを指定できます。
また、必ずnamespaceメソッドの記述は、resources :usersが他にある場合それよりも上の行に書きましょう。
もし下の行に書くと、先にusersのshowアクション(users/:id)が読み込まれ、実際に検索した際にエラーが生じてしまいます。
###アクションをコントローラに定義
searches_controllerにuser.rbに定義したsearchメソッドを使用し検索結果の一覧を表示するindexアクションを定義していきます。
def index
@tweets = Tweet.search(params[:keyword])
end
###検索フォームの作成
= form_with(url: users_searches_path, local: true, method: :get, class: "search_form") do |f|
= f.text_field :keyword, placeholder: "Name", class: "search_input"
= f.submit "Search", class: "search_btn"
searchesコントローラーのindexアクションへのパスを指定し、フォームに入力された内容をsearchメソッドの引数として渡します。
###最後にsearches/index.html.erbを作成し編集
検索後に表示するビューを作成します。
#おわり
以上の方法でユーザーを名前で検索することが可能になりました。
最後まで閲覧いただきありがとうございました。