今回オリジナルアプリの作成で、投稿したコンテンツをジャンル別に表示する機能を調べて実装できたのでここに記録。
こちらもransackというgemを導入することで実装できた。
ransackは複雑な検索機能を可能にするgemで、今回は実装しなかったがソート機能も可能
Gemfileにgem "ransack"
と記載
ターミナルでbundle install
次に新しいアクションをルーティングに設定するためにroutes.rb
get '/movie/genre', to: "movies#genre"
genreアクションが実行されると、ジャンル検索結果のページが表示されるように設定。
controllerにbeforeアクションを設定
before_action :search_genre_movie, only: [:index, :genre]
(省略)
private
def search_genre_movie
@q = Movie.ransack(params[:q])
end
privateメソッドにsearch_genre_movieメソッドを作成。これを実行すると、@q = Movie.ransack(params[:q])という検索オブジェクトが作成される。
次にアクションの定義
def genre
@movies = @q.result
genre_id = params[:q][:genre_id_eq]
@genre = Genre.find_by(id: genre_id)
end
genreメソッド内に@movies = @q.resultを記入し、検索結果を取得。この時、binding.pryでparams[:q]にはcategory_id_eqの中にidが入っていることを確認。
次に検索ボックスを作成 今回はindex.html.erbに記載
<%= search_form_for @q, url: photo_category_path do |f| %>
<%= f.collection_select :category_id_eq, Category.where.not(id: 0), :id, :name, include_blank: "カテゴリー検索" %>
<%= f.submit '検索' %>
<% end %>
ransackのヘルパーメソッドsearch_form_forメソッドで、検索フォームを作成。引数に検索オブジェクト@qを渡し、urlのパス名はgenreアクションのパス名(rails routesで確認を)。
パスの指定が完了したので次は実際に検索を行なった後のビューの作成
今回はgenre.html.erbにindex.html.erbと同様のビューに設定。
<ul class='movie-lists'>
<%@movies.each do |movie| %>
<% if current_user.id == movie.user_id %>
<li class="movie-contents">
<div class="box-movie-genre">
<%=movie.genre.name%>
</div>
<%= link_to movie_path(movie.id), class:"link" do %>
<div class="box-movie-image">
<%= image_tag movie.image, size: '200x210',class: "movie-img" %>
</div>
<div class="box-movie-title">
<%= movie.title %>
</div>
<%end%>
</li>
<%end%>
<%end%>
</ul>
これでプルダウン検索機能実装
補足情報として、3行目のif文に関しては、今回各ユーザーが他者の投稿内容は一切閲覧できない使用にするため。検索で得たgenre_idを持つmoviesの中から、現在のユーザーと投稿したユーザーが同一であれば表示するという条件で表示。こうすることで異なるユーザーの投稿は表示されない。