【Rails】投稿した写真の検索機能(フリーワード/カテゴリー/タグ)を実装したい
概要
投稿した写真を下記の方法で検索できるように実装をしていきます。
解決方法
①searchコントローラーを生成して、フリーワード/カテゴリー/タグそれぞれのアクションを記述する。
②ビューファイル内にフリーワード/カテゴリー/タグそれぞれの検索時にコントローラーへ送るパラメーターとして、値(value)と検索方法(how)を指定する記述をする。
③パラメーター内のhowによって実行する検索アクションを条件分岐させる。
※前提として、すでにsearchコントローラーは完了しているとします。
導入方法は下記の通りです。
terminal
$rails g controller search
routes.rb
Rails.application.routes.draw do
get 'search/search'
--中略--
end
searchコントローラーを生成して、フリーワード/カテゴリー/タグそれぞれのアクションを記述する
app/controllers/search_controller.rb
class SearchController < ApplicationController
def search
@gender = Gender.find([2, 3, 4])
@price = Price.find([2, 3, 4, 5, 6])
#ActiveHashを使用してモデル内に直接記述することで、データベースへ保存せずにデータを取り扱う
@tags = Tag.all.order('created_at DESC')
@value = params['search']['value']#検索時にパラメーターとして送る値を代入
@how = params['search']['how']#検索時にパラメーターとして送る検索方法を代入
@datas = search_for(@how, @value)#検索結果を代入
end
private
def keyword(value)
Photo.where('title LIKE(?) OR description LIKE(?)', "%#{value}%", "%#{value}%")
#photosテーブルのtitle, descriptionカラムからフリーワード検索
end
def match_gender(value)
Photo.where(gender_id: value)
#パラメーターのvalueと同じgender_idを持つデータを検索
end
def match_price(value)
Photo.where(price_id: value)
#パラメーターのvalueと同じprice_idを持つデータを検索
end
def match_tag(value)
Photo.where(id: PhotoTag.select(:photo_id)#PhotoTagテーブルのphoto_idカラムのデータを取得
.where(tag_id: value)#重複したphoto_idも含め、パラメーターのvalueと同じtag_idを持つデータを検索
.group(:photo_id))#photo_idでグループ化して重複したphoto_idはまとめる
end
ビューファイル内にフリーワード/カテゴリー/タグそれぞれの検索時にコントローラーへ送るパラメーターとして、値(value)と検索方法(how)を指定する記述をする
app/views/shared/_header.html.erb
<%= form_with(url: search_search_path, local: true, method: :get, class: "d-none d-md-inline-block form-inline ms-auto me-0 me-md-3 my-2 my-md-0") do |form| %>
<div class="input-group">
<%= form.text_field 'search[value]', placeholder: "キーワードで検索", class: "form-control", 'search[how]': "keyword" %>
<%= form.submit "検索", class: "btn btn-primary", id: "btnNavbarSearch" %>
</div>
<% end %>
app/views/shared/_side_nav.html.erb
--中略--
<% @gender.each do |gender| %>
<%=link_to gender.name, search_search_path('search[value]': gender.id, 'search[how]': "match_gender"), class:"nav-link" %>
<% end %>
--中略--
<% @price.each do |price| %>
<%=link_to price.name, search_search_path('search[value]': price.id, 'search[how]': "match_price"), class:"nav-link" %>
<% end %>
--中略--
<% @tags.each do |tag| %>
<%=link_to "##{tag.name}", search_search_path('search[value]': tag.id, 'search[how]': "match_tag") , class:"nav-link" %>
<% end %>
--中略--
パラメーター内のhowによって実行する検索アクションを条件分岐させる
app/controllers/search_controller.rb
class SearchController < ApplicationController
--中略--
private
--中略--
def search_for(how, value)
case how #パラメーターのhowによって検索アクションを条件分岐させる
when 'match_gender'
match_gender(value)
when 'match_price'
match_price(value)
when 'match_tag'
match_tag(value)
else
keyword(value)
end
end
参考
app/controllers/search_controller.rb
class SearchController < ApplicationController
def search
@gender = Gender.find([2, 3, 4])
@price = Price.find([2, 3, 4, 5, 6])
#ActiveHashを使用してモデル内に直接記述することで、データベースへ保存せずにデータを取り扱う
@tags = Tag.all.order('created_at DESC')
@value = params['search']['value']#検索時にパラメーターとして送る値を代入
@how = params['search']['how']#検索時にパラメーターとして送る検索方法を代入
@datas = search_for(@how, @value)#検索結果を代入
end
private
def keyword(value)
Photo.where('title LIKE(?) OR description LIKE(?)', "%#{value}%", "%#{value}%")
#photosテーブルのtitle, descriptionカラムからフリーワード検索
end
def match_gender(value)
Photo.where(gender_id: value)
#パラメーターのvalueと同じgender_idを持つデータを検索
end
def match_price(value)
Photo.where(price_id: value)
#パラメーターのvalueと同じprice_idを持つデータを検索
end
def match_tag(value)
Photo.where(id: PhotoTag.select(:photo_id)#PhotoTagテーブルのphoto_idカラムのデータを取得
.where(tag_id: value)#重複したphoto_idも含め、パラメーターのvalueと同じtag_idを持つデータを検索
.group(:photo_id))#photo_idでグループ化して重複したphoto_idはまとめる
end
app/views/shared/_header.html.erb
<%= form_with(url: search_search_path, local: true, method: :get, class: "d-none d-md-inline-block form-inline ms-auto me-0 me-md-3 my-2 my-md-0") do |form| %>
<div class="input-group">
<%= form.text_field 'search[value]', placeholder: "キーワードで検索", class: "form-control", 'search[how]': "keyword" %>
<%= form.submit "検索", class: "btn btn-primary", id: "btnNavbarSearch" %>
</div>
<% end %>
app/views/shared/_side_nav.html.erb
--中略--
<% @gender.each do |gender| %>
<%=link_to gender.name, search_search_path('search[value]': gender.id, 'search[how]': "match_gender"), class:"nav-link" %>
<% end %>
--中略--
<% @price.each do |price| %>
<%=link_to price.name, search_search_path('search[value]': price.id, 'search[how]': "match_price"), class:"nav-link" %>
<% end %>
--中略--
<% @tags.each do |tag| %>
<%=link_to "##{tag.name}", search_search_path('search[value]': tag.id, 'search[how]': "match_tag") , class:"nav-link" %>
<% end %>
--中略--
パラメーター内のhowによって実行する検索アクションを条件分岐させる
app/controllers/search_controller.rb
class SearchController < ApplicationController
--中略--
private
--中略--
def search_for(how, value)
case how #パラメーターのhowによって検索アクションを条件分岐させる
when 'match_gender'
match_gender(value)
when 'match_price'
match_price(value)
when 'match_tag'
match_tag(value)
else
keyword(value)
end
end
参考
app/controllers/search_controller.rb
class SearchController < ApplicationController
--中略--
private
--中略--
def search_for(how, value)
case how #パラメーターのhowによって検索アクションを条件分岐させる
when 'match_gender'
match_gender(value)
when 'match_price'
match_price(value)
when 'match_tag'
match_tag(value)
else
keyword(value)
end
end
Author And Source
この問題について(【Rails】投稿した写真の検索機能(フリーワード/カテゴリー/タグ)を実装したい), 我々は、より多くの情報をここで見つけました https://qiita.com/nakachan-ing/items/b28eda568ad73324761a著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .