Rails несколько параметров поиска и значений по умолчанию

У меня есть форма для поиска модели инцидентов с 3 полями: incidenttype, dayofweek и created_at. В моем методе incidents.index я проверяю, присутствует ли параметр поиска. Затем отфильтруйте результаты на основе диапазона created_at и т. д. Как мне настроить это так, чтобы, если бы параметры dayofweek и incidenttype были пустыми или пустыми, он просто не использовал бы их в фильтре запроса? По сути, если ничего не было выбрано, не используйте эти параметры, а только created_at.

Индексный метод контроллера инцидентов:

def index
  if params[:search] && params[:search][:created_at].present?
    start_date, end_date = params[:search][:created_at].split(' - ')
    @incidents = Incident.where(created_at: start_date..end_date).where(dayofweek: params[:search][:dayofweek]).where(incidenttype: params[:search][:incidenttype])
    @dayofweek = params[:search][:dayofweek]
    @incidenttypes = Incident.order("incidenttype").distinct.pluck(:incidenttype)
  else
    @incidents = Incident.all
    @incidenttypes = Incident.order("incidenttype").distinct.pluck(:incidenttype)
  end
end

Форма:

<%= form_for(:search, url: incidents_path, method: :get) do |f| %>
  <div class="ui-bordered px-4 pt-4 mb-4">
    <div class="form-row">
      <div class="col-md mb-4">
        <label class="form-label">Type</label>
        <%= f.select :dayofweek, Incident.dayofweeks.keys, {:include_blank=> 'Any days', :selected => @dayofweek}, class: 'custom-select' %>
      </div>
      <div class="col-md mb-4">
        <label class="form-label">Incident Type</label>
        <%= f.select :incidenttype, options_for_select(@incidenttypes, :selected => params[:search][:incidenttype]), {include_blank: true}, class: 'form-control' %>
      </div>
      <div class="col-md mb-4">
        <label class="form-label">Created date</label>
        <%= f.text_field :created_at, class: 'form-control', id: 'tickets-list-created', :autocomplete => :off, value: created_at_from_parameters %>
      </div>
      <div class="col-md col-xl-2 mb-4">
        <label class="form-label d-none d-md-block">&nbsp;</label>
        <button type="submit" class="btn btn-secondary btn-block">Show</button>
      </div>
    </div>
  </div>
<% end %>

Есть мысли о том, как это настроить?

0
0
36
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Замените свой метод индекса на:

def index
  @incidenttypes = Incident.order(:incidenttype).distinct.pluck(:incidenttype)
  @incidents = if params[:search] && params[:search][:created_at].present?
                 @dayofweek = params[:search][:dayofweek]
                 start_date, end_date = params[:search][:created_at].split(' - ')
                 filters = { created_at: start_date..end_date }
                 [:dayofweek, :incidenttype].each do |filter|
                   next if params[:search][filter].blank?  
                   filters.merge!({ filter => params[:search][filter] } )
                 end
                 Incident.where(filters)
               else
                 Incident.all
               end
end

Работает отлично. Спасибо! Интересное решение.

spacerobot 31.10.2018 18:27

Одна проблема. Когда я сначала перехожу на страницу, я получаю сообщение об ошибке для выбранного значения: <%= f.select :incidenttype, options_for_select(@incidenttypes, :selected => params[:search][:incidenttype]), {include_blank: true}, class: 'form-control' %> Я получаю ошибку undefined method `[] 'для nil: NilClass. Какие-нибудь рекомендации по этому поводу?

spacerobot 31.10.2018 19:15

Убедитесь, что params[:search] присутствует, прежде чем показывать его выбранным.

Pramod Shinde 01.11.2018 10:18

Спасибо вам за помощь.

spacerobot 01.11.2018 19:17

Другие вопросы по теме