Расширенный поиск по нескольким ассоциациям в Rails - PullRequest
1 голос
/ 22 декабря 2011

Я пытаюсь создать расширенный поиск для моей модели кандидата. Давайте представим, что у него есть пара полей + несколько ассоциаций, таких как has_many: languages & has_many: skills. Сейчас я строю запрос так:

query = Candidate.select("*")
if position_name
  query = query.where('position_name LIKE ? OR position_name IS NULL',"%#{position_name}%")
end 

if salary
  query = query.where('salary <= ? OR salary IS NULL',salary)
end

и так далее ...

Теперь я хочу добавить более сложные условия, такие как поиск пользователей, у которых есть только такие навыки, как PHP и Java (поэтому возвращаются только те пользователи, у которых есть оба навыка)

Это работает, но только когда я вставляю OR

  query = query.joins(:skills)
  query = query.where('`skills`.`name` = ? OR `skills`.`name` = ?',"Java","PHP")

Кроме того, я хотел бы то же самое для языков (плюс, язык имеет language.name & language.level)

Может кто-то указывает мне, в каком направлении смотреть? А также как построить такое условие, когда я могу использовать несколько навыков или несколько языков?

1 Ответ

3 голосов
/ 22 декабря 2011

Посмотрите на различные поисковые камни, такие как Ransack, Metawhere или Searchlogic

http://rubygems.org/gems/ransack

https://github.com/railsdog/searchlogic

И Ransack, и Searchlogic позволяют выполнять поиск по соответствующим моделями вы можете использовать области для ограничения параметров поиска.

Пример поиска параметров для Searchlogic.

[search][admitted_gte]  

[search][admitted_lte]  

[search][aetiology_like_any][]  VIRUS

[search][at_risk_gte]   

[search][at_risk_lte]   

[search][died_gte]  

[search][died_lte]  

[search][gezi_reference_like]   

[search][id]    

[search][incidents_location_encrypted_postcode_like]    

[search][lab_confirmed_gte] 

[search][lab_confirmed_lte] 

[search][onset_first_after] 

[search][onset_first_before]    

[search][onset_last_after]  

[search][onset_last_before] 

[search][outbreak_type_equals_any][]    FOODBORNE

[search][point_source_date_after]   

[search][point_source_date_before]  

[search][total_affected_gte]    

[search][total_affected_lte]    

[search][user_reference_like]   

[search][year_equals_any][] 2010

search[order]   descend_by_id

Outbreak_Controller.rb Действие Index возвращает результаты поискового запроса.Из 17 поисковых параметров требуется только один поисковый логический вызов @ search = Outbreak.search(params[:search]).Параметры заносятся в белый список со списком разрешенных параметров поиска - код не показан.

def index

          #set the default index order to be descending Outbreak id
          if !params[:search][:order]
              params[:search][:order] = "descend_by_id"  
          end
          if params[:search][:bacterial_agents_bacterium_name_like_any] != nil && !params[:search][:bacterial_agents_bacterium_name_like_any].empty?
              params[:search][:bacterial_agents_category_like] = "CAUSATIVE"
          end
          if params[:search][:viral_agents_virus_name_like_any] != nil && !params[:search][:viral_agents_virus_name_like_any].empty?
              params[:search][:viral_agents_category_like] = "CAUSATIVE"
          end
          if params[:search][:protozoal_agents_protozoa_name_like_any] != nil && !params[:search][:protozoal_agents_protozoa_name_like_any].empty?
              params[:search][:protozoal_agents_category_like] = "CAUSATIVE"
          end
          if params[:search][:toxic_agents_toxin_name_like_any] != nil && !params[:search][:toxic_agents_toxin_name_like_any].empty?
              params[:search][:toxic_agents_category_like] = "CAUSATIVE"
          end
  #Outbreak.search takes all of the given params and runs it against the Outbreak model and it's associated models
  @search = Outbreak.search(params[:search])
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...