対象者
- 検索機能をransackなしで実装したい方
- 検索を非同期通信で行いたい方
目的
- 非同期で検索結果を作成する
実際の手順と実例
1.前提
- Rails 5.2.5
- userコントローラーにsearchアクション加えることで実装
- 本(bookモデル)とUserモデルを実装済
- アソシエーション設定(ユーザー:本 = 1:N)
- 本の一覧ページに検索結果を表示
イメージこんな感じ
2.Controllerとルーティングの設定
Userコントローラーに下記を追記します
Users_controller.rb
# 一部抜粋
def search
@user = User.find(params[:user_id])
@books = @user.books
@book = Book.new
if params[:created_at] == ""
@search_book = "日付を選択してください"#①
else
create_at = params[:created_at]
@search_book = @books.where(['created_at LIKE ? ', "#{create_at}%"]).count#②
end
end
①if文で分岐させて空欄なら日付を選択するように表示します
②.countメソッドで検索してヒットした本を投稿した日付の投稿数を@search_bookで定義します。
ルーティングは下記の通り
routes.rb
resources :users, only: [:index, :show, :edit, :update] do
get "search", to: "users#search"
end
ユーザーを親要素としてネストさせてます。
3.Viewの設定
ここでは本の一覧ページに表示します。
index.html.erb
<%= form_with url: user_search_path(@user), method: :get do |f| %>
<%= f.date_field :created_at %> #①
<%= f.submit '検索', class: 'btn btn-primary' %>
<% end %>
<div id="search_result"> #②
<% if @search_book.present? %>
<%= render 'search', search_book: @search_book %> #③
<% end %>
</div>
①このフィールドで年/月/日が表示されます
②これでjsファイルを呼び出します。
③検索結果を部分テンプレート化しています。
検索結果は以下の通り
Usersフォルダ内に_search.html.erbを作成してます
app/views/users/_search.html.erb
<h4>検索結果</h4>
<table class='table table-bordered'>
<thead>
<tr>
<th>投稿数</th>
</tr>
</thead>
<tbody>
<tr>
<td><%= search_book %></td>
</tr>
</tbody>
</table>
4.非同期通信設定
Viewで設定したsearch_resultを呼び出します
app/views/users/search.js.erb
$("#search_result").html("<%= j(render 'search', search_book: @search_book) %>");
これで実装完了です。
投稿者コメント
これcount以外もできるかなと挑戦するために、
まず、手順思い出そうと思ってアウトプットしてみました。
My Profile
プログラミング学習歴3ヶ月目のアカウントです!
プログラミングスクールで学んだ内容や自分が躓いた箇所等のアウトプットの為に発信しています。
また、プログラミング初学者の方にわかりやすく、簡潔にまとめて情報共有できればと考えています。
もし、投稿した記事の中に誤り等ございましたら、コメント欄でご教授いただけると幸いです。