filterrific: как выполнить поиск по нескольким словам? - PullRequest
0 голосов
/ 23 мая 2018

Я использую filterrific для создания фильтра.

Предположим, я получил объект с locality, установленным в "Нью-Йорк".

С настоящим кодом этоработает, если я ищу только одно слово, например: «Новый».Если я напишу «Нью-Йорк», ничего не появится.

В примере filterrific фильтр позволяет пользователю написать несколько слов в «query».

модель

  scope :search_query, lambda { |query|
  return nil  if query.blank?
    terms = query.downcase.split(/\s+/)
    terms = terms.map { |e|
      (e.gsub('*', '%') + '%').gsub(/%+/, '%')
    }
    num_or_conds = 2
    where(
      terms.map { |term|
        "(LOWER(title) LIKE ? OR LOWER(locality) LIKE ?)"
      }.join(' AND '),
      *terms.map { |e| [e] * num_or_conds }.flatten
    )
  }



filterrific(
   default_filter_params: {},
   available_filters: [
     :search_query
   ]
 )

контроллер

def index
   @filterrific = initialize_filterrific(
     @ads,
     params[:filterrific]
   ) or return
    @ads = @filterrific.find.page(params[:page])
end

просмотр

  = form_for_filterrific @filterrific do |f|
    div
      | Search
      = f.text_field :search_query, class: 'skills field w-input filterrific-periodically-observed', placeholder: "Job title, keywords, skills..."

      = f.submit 'GO !', {class: "submit-b w-button"}

РЕДАКТИРОВАТЬ

журналы

 Ad Load (1.2ms)  SELECT  "ads".* FROM "ads" WHERE (publishing_at <= '2018-05-24') AND (expiring_at >= '2018-05-24') AND ((LOWER(title) LIKE 'new%' OR LOWER(locality) LIKE 'new%') AND (LOWER(title) LIKE 'york%' OR LOWER(locality) LIKE 'york%')) LIMIT $1 OFFSET $2  [["LIMIT", 20], ["OFFSET", 0]]

1 Ответ

0 голосов
/ 24 мая 2018

Проблема видна из вашего журнала SQL:

...
AND ((LOWER(title) LIKE 'new%' OR LOWER(locality) LIKE 'new%')
AND (LOWER(title) LIKE 'york%' OR LOWER(locality) LIKE 'york%'))

Требуемый SQL должен быть:

...
AND ((LOWER(title) LIKE '%new%' OR LOWER(locality) LIKE '%new%')
AND (LOWER(title) LIKE '%york%' OR LOWER(locality) LIKE '%york%'))

Поскольку "new" находится на начало из locality, оно соответствует;но поскольку "york" не в начале, оно не соответствует.

Чтобы исправить это, вы можете заменить строку:

(e.gsub('*', '%') + '%').gsub(/%+/, '%')

на:

('%' + e.gsub('*', '%') + '%').gsub(/%+/, '%')
...