#ruby-on-rails #ruby #filter
#ruby-on-rails #ruby #Фильтр
Вопрос:
Я работаю над проектом, в котором мы должны фильтровать события на основе местоположения, даты, вида спорта и уровня квалификации. На данный момент каждый фильтр работает индивидуально, но я не могу связать их, чтобы получить еще более конкретные результаты.
Это то, что у меня есть в моей модели.
include PgSearch::Model
pg_search_scope :global_search,
against: [:location, :sport, :level, :date]
pg_search_scope :date_search,
against: [:date]
pg_search_scope :sport_search,
against: [:sport],
using: {
tsearch: { prefix: true }
}
pg_search_scope :location_search,
against: [:location],
using: {
tsearch: { prefix: true }
}
pg_search_scope :level_search,
against: [:level]
enum level: { Beginner: 1, Intermediate: 2, Advanced: 3, Pro: 4 }
И это в моем контроллере.
def index
if params[:search][:location].present?
@events = policy_scope(Event).location_search(params[:search][:location])
elsif params[:search][:sport].present?
@events = policy_scope(Event).sport_search(params[:search][:sport])
elsif params[:search][:date].present?
@events = policy_scope(Event).date_search(params[:search][:date])
elsif params[:search][:level].present?
@events = policy_scope(Event).level_search(params[:search][:level])
else
@events = policy_scope(Event)
end
@markers = @events.geocoded.map do |event|
{
lat: event.latitude,
lng: event.longitude
}
end
end
И это мои фильтры
<div id="collapseFilters" class="container collapse form">
<%= simple_form_for :search, url: events_path, method: "GET", html: { class: 'form-block' } do |f| %>
<%= f.input :date, as: :string, required: false, input_html: {class: "datepicker"} %>
<%= f.input :level, collection: Event.levels.map{ |l| [l.first, l.second] }, required: false, label_method: :first, value_method: :second%>
<%= f.input :location, required: false, placeholder: 'Enter a location for your event' %>
<%= f.button :submit, 'Search', class: "btn btn-primary btn-lg btn-form mt-3" %>
<% end %>
</div>
Как я мог бы связать их в параметрах, чтобы я мог использовать более одного фильтра одновременно?
Ответ №1:
Вы можете обновить свой контроллер:
def index
@events = policy_scope(Event)
@events = @events.location_search(params[:search][:location]) if params[:search][:location].present?
@events = @events.sport_search(params[:search][:sport]) if params[:search][:sport].present?
@events = @events.date_search(params[:search][:date]) if params[:search][:date].present?
@events = @events.level_search(params[:search][:level]) if params[:search][:level].present?
@markers # ...
end
или даже (если это достаточно понятно для вас)
def index
@events = policy_scope(Event)
%i[location sport date level].each do |filter|
next unless params[:search][filter].present?
@events = @events.public_send("#{filter}_search", params[:search][filter])
end
@markers # ...
end
если я правильно понимаю, как работает этот драгоценный камень.
Комментарии:
1. Привет, я автор pg_search. Да, это должно сработать.
Ответ №2:
Вы должны использовать опцию multisearchable, как описано в документации https://github.com/Casecommons/pg_search