2015-03-26 2 views
1

У меня есть простая форма поиска рельсов, которая будет просматривать все сообщения и сопоставлять некоторые ключевые слова, но мне также хотелось бы, чтобы они соответствовали некоторым атрибутам.Поиск по Rails с несколькими параметрами

У меня есть это как мой взгляд:

<%= form_tag(grant_applications_path, :method => "get", id: "search-form") do %> 
    <%= text_field_tag :search, params[:search], placeholder: "Search Terms" %> 


    <%= check_box_tag :search, "Pending", params[:search] %> 
    <label>Pending</label> 

    <%= check_box_tag :search, "Granted", params[:search] %> 
    <label>Granted</label> 

    ... 
    <%= submit_tag "Search", :name => nil, class: "btn btn-rimary" %> 

<% end %> 

Модель:

def self.search(query) 
    where("grant_request LIKE ? OR contact_email LIKE ? 
      OR contact_person LIKE ? OR status LIKE ?", "%#{query}%","%#{query}%", 
      "%#{query}%","%#{query}%") 
    end 

Контроллер:

def index 
    if params[:search] 
     @grant_application = GrantApplication.search(params[:search]).paginate(page: params[:page], :per_page => 10) 
    else 
     @grant_application = GrantApplication.all.paginate(page: params[:page], :per_page => 10) 
    end 
end 

Любые предложения о том, как я должен добавить в CheckBox фильтры при поиске ?

ответ

0

Предположим, вы хотите получить систему поиска соответствия ключевых слов с обычным полем ввода текста поиска.

1) Создайте новое поле ввода текста с: атрибутом keyword и параметром просто: выполните поиск, как вы уже использовали.

2) позволяет: атрибут ключевого слова на контроллере, если это Rails 4+ или на модели, если это не Rails 4.

3) Никогда не напрямую использовать ввод пользователя. Всегда фильтруйте его по соображениям безопасности. Используйте «before_filter» в контроллере. Проверьте, не пусто ли он, есть теги html или javascript-скрипты и т. Д. Обычно я дезинфицирую его с помощью полезного метода «дезинфекции» драгоценного камня.

4) теперь, получите ключевые слова пользователя, разделив каждое слово на пробел.

5) написать поисковый запрос с ключевыми словами в модели

6) выполнять и вернуть его.

Я отвечу более подробно, если вы зададите дополнительные вопросы.

0

Все поисковые запросы предназначены для создания правильного оператора sql. В Rails у вас могут быть вспомогательные классы для этого и сделать вашу жизнь проще.

1) Более необходимые линии, те, что вам может понадобиться и в других классах поиска, поместите их в utils.rb:

module Utils 

    def is_like(query) 
    "%" + query + "%" 
    end 

    def case_insensitive_search(query) 
    "lower(#{query}) like :#{query}" 
    end 

end 

2) Тогда для модели. Они могут быть более сложными, чем 3-х полей ... как этот помощник класса под названием search_posts.rb:

include Utils 

class SearchPosts 
    attr_reader :where, :what, :order 

    def initialize(author_id, publish, query, order_by_title, desc_order) 
    @where = "" 
    @what = {} 
    @order = "" 

    commit_search(author_id, publish, query, order_by_title, desc_order) 
    end 

    private 

    def commit_search(author_id, publish, query, order_by_title, desc_order) 

    unless author_id.nil? 
     @where << "author_id = #{author_id}" 
     @what[:author_id] = author_id 
    end 

    unless publish.nil? 
     unless @where.blank? 
     @where << ' AND ' 
     end 

     @where << "publish = #{publish}" 
     @what[:publish] = publish 
    end 

    unless query.blank? 
     unless @where.empty? 
     @where << ' AND ' 
     end 

     @where << "(#{case_insensitive_search(:title)}" 
     @what[:title] = is_like(query) 

     @where << ' OR ' << "#{case_insensitive_search(:content)})" 
     @what[:content] = is_like(query) 
    end 

    if order_by_title 
     @order << 'title ' 
    else 
     @order << 'updated_at ' 
    end 

    if desc_order 
     @order << 'DESC' 
    else 
     @order << 'ASC' 
    end 
    end 

end 

3) У вас контроллер, просто поймать Params вы передаете и построить поиск. Помните, что все готово для создания правильного оператора sql, и ваш код может сделать это за вас. ;)

class PostsController < ApplicationController 
... 
def search # or any other action... 
    if params[:query_posts].present? 
    # this is the only couple of lines you will have to be changing to query anything about your model 
    search = SearchPosts.new(nil, true, params[:query_posts], true, false) 
    @posts = Post.where(search.where, search.what).order(search.order) 
    end 
end 
... 
end 

В результате SQL заявление, которое будет передано в активной записи является:

SELECT `posts`.* FROM `posts` WHERE ((lower(title) like '%query%' OR lower(content) like '%query%')) ORDER BY updated_at DESC 
Смежные вопросы