オリジナルの写真投稿アプリを制作した際にActiveHashを用いたプルダウンメニューでの検索機能を実装したので備忘録に残します。
ransackを用いて実装しています。
ActiveHashの作成については書いていません。
Gemの導入
Gemfileの最下部へ以下を記述してインストール
gem 'ransack'
bundle install
ルーティングを設定
検索結果を一覧で表示したいので検索結果ページへのルーティングを記述する
collectionオプションでpostsコントローラー内のseachアクションに繋がるように設定
resources :posts do
collection do
get 'search'
end
end
コントローラーにseachアクションを記述
def search
@q = Post.ransack(params[:q])
@items = @q.result.order('created_at DESC')
end
ransackメソッドで検索オブジェクトを生成し変数に代入
params[:q]にはこの後に作成するフォームから送られてくるパラメーターが入る
resultメソッドで検索結果を取得する
検索フォームを作成
どのページからでも検索できるようにヘッターに記述
検索フォームを実装する際に使うsearch_form_forメソッドの引数には、コントローラーで定義した@qを渡す
<%= search_form_for @q, url: search_posts_path do |f| %>
<div class="search-field">
<% f.label :brand_id_eq %>
<br>
<%= f.collection_select(:brand_id_eq, Brand.all, :id, :name, {}) %>
<%= f.submit '検索する', id:"submit-btn" %>
</div>
<% end %>
labelにはActiveHashを指定し、完全に一致する検索結果を表示したいので_eqオプションを追記
f.collection_selectにもActiveHashを指定する
第一引数がカラム名、第二引数が配列データ、第三引数が表示する際に参照するDBカラム名、第四引数が実際に表示するカラム名、第五引数は何も選択していない時に表示される内容だけどActiveHashの方で設定してあるので空にする
これで検索フォームの作成はできたが今のままだと何も選択しなくても検索ボタンが押せてしまうので選択してからでないとボタンが押せないようにする
app/javascript下にsubmit.jsを作成
下記の記述で選択してからでないとボタンが押せないように設定できる
window.addEventListener('DOMContentLoaded', function(){
$( '#submit-btn' ).prop( 'disabled', true );
$('#q_brand_id_eq').on('change', function(){
const selected = $('#q_brand_id_eq').val();
if( selected !== '' ){
$('#submit-btn').prop('disabled', false);
} else {
$('#submit-btn').prop('disabled', true);
}
})
});
検索結果ページの作成
<div class="search-tittle">ブランド検索一覧</div>
<div class="index-main">
<% @items.each do |post| %>
<div class="index-post-wrapper">
<div class="index-post-items">
<div class="index-post-image">
<% post.images.each do |images| %>
<%= image_tag images, class: :post__img %>
<% end %>
</div>
<ul class="index-post-list">
<li class="index-post-list-first">投稿日:<%= post.created_at.strftime('%Y/%m/%d') %></li>
<li class="index-post-list-first">ブランド:<%= post.brand.name %></li>
<li class="index-post-list-first">投稿者: <%= "@" + post.user.name %></li>
<li class="index-post-list-first"> 選択頻度:<%= post.washing_frequency %></li>
<li class="index-post-list-first">着用年数:<%= post.wearing_years %></li>
<li class="index-post-list-first"><%= link_to '詳細を見る', post_path(post.id), class: "root-show-btn" %> </li>
</ul>
</div>
</div>
<% end %>
<% if @items.blank? then %>
<div class="blank-tittle">選択したブランドの投稿はありません</div>
<% end %>
</div>
以上が検索機能の実装が終わりました。
検索機能の実装自体は調べればすぐ出てくるしプルダウンメニューはすでに作成してあったので意外と簡単だったんですが選択しないとボタンが押せないようにするのが大変でした。
JavaScriptの仕組みをもっと理解しなければ…