Rails: создание поискового фильтра на основе выпадающих списков для базы данных Mongoid - PullRequest
0 голосов
/ 31 августа 2018

На моей странице индекса у меня есть несколько выпадающих меню, которые пользователь может выбрать в качестве фильтра для поиска в коллекции Mongo. Эти выпадающие списки соответствуют полям, установленным в моей модели. Существует также открытое поле ввода текста, которое они могут использовать для поиска текстовых полей «имя сценария» и «тело сценария» в коллекции. Кажется, я не могу найти много документации о том, как связать Mongoid запросы, чтобы сузить результаты поиска.

На странице просмотра index.erb есть form_tag с различными селекторами для полей, по которым пользователь должен выполнять поиск, и текстовым вводом для имени сценария и полей тела.

Вот мой контроллер индекса:

  def index
@scenarios = if params[:search]
               Scenario.search(params)
             else
               Scenario.all
             end
end

И мои "сценарии" модели:

class Scenario
  include Mongoid::Document
  field :submitter, type: String
  field :scenario_name, type: String
  field :scenario_body, type: String
  field :creation_date, type: Date
  field :modified_date, type: Date
  field :test_type, type: String
  field :application, type: String
  field :pillar, type: String

  def self.search(search)
    self.or({submitter: /.*#{search[:submitter]}.*/i},
            {scenario_name: /.*#{search[:search]}.*/i},
            {scenario_body: /.*#{search[:search]}.*/i},
            {creation_date: search[:creation_date]},
            {modified_date: search[:modified_date]},
            {test_type: /.*#{search[:test_type]}.*/i},
            {application: /.*#{search[:application]}.*/i},
            {pillar: /.*#{search[:pillar]}.*/i})
  end
end

Как мне создать метод или запрос, который может фильтровать по одному, многим, всем параметрам выпадающего списка и открытому текстовому поиску?

1 Ответ

0 голосов
/ 10 сентября 2018

Вот так я и поступил. Хотя это и не похоже на рельсы, но работает.

В модели сценария:

  def self.search(search)
    search_array = [{scenario_name: (/.*#{search[:search]}.*/i if search[:search].present?)},
                    {scenario_body: (/.*#{search[:search]}.*/i if search[:search].present?)}]

    search_array.map {|a| a.reject! {|k, v| v.nil?}}
    search_array.delete_if {|hash| hash.empty?}

    select_array = [{submitter: (search[:submitter] if search[:submitter].present?)},
                    {test_type: (search[:test_type] if search[:test_type].present?)},
                    {application: (search[:application] if search[:application].present?)},
                    {pillar: (search[:pillar] if search[:pillar].present?)}]

    select_array.map {|a| a.reject! {|k, v| v.nil?}}
    select_array.delete_if {|hash| hash.empty?}

    mongo_query = ['$and' => (select_array if select_array.present?), '$or' => (search_array if search_array.present?)]
    mongo_query.map {|a| a.reject! {|k, v| v.nil?}}
    mongo_query.delete_if {|hash| hash.empty?}

    where(mongo_query[0]).to_a
  end
...