2016-10-11 7 views
0

EDIT 2Rails 4.2 Использование form_tag для создания поиска, но без использования строки запроса Params

Похожие вопросы here.

EDIT

Это маршрут я должен представить:

get '/s/:term', controller: :products, action: :search, as: :search_products 

У меня есть форма поиска, как это:

<%= form_tag(search_products_path, :method => "get", id: "search-form", name: "f1", enforce_utf8: false) do %> 
    <div class="input-group"> 
     <%= text_field_tag :search, params[:search], placeholder: "Search products", class: "form-control", name: "search" %> 
     <div class="input-group-btn"> 
     <button class="btn btn-secondary"> 
      <span class="glyphicon glyphicon-search"></span> 
     </button> 
     </div> 
    </div> 
    <% end %> 

Но это создает URL, как это :

domain/s?search=[user input] 

мне нужен URL, чтобы быть, как это вместо:

domain/s/[user_input] 

Да, я знаю, что это не следует Rails конвенции. На этот момент мне было все равно, мне просто нужно разобраться.

Спасибо.

+0

Это не стандарт Rails, это стандарт HTML/HTTP - проблема в том, что ваша форма использует 'get' вместо' post', и это стандартный URL-адрес для запросов GET ... –

+0

Я знаю, что это не стандарт. Я говорю это в вопросе. Я добавил редактирование, чтобы показать маршрут, который я пытаюсь удалить этой формой. – rmcsharry

+0

Это не может быть POST, потому что это должно быть «permalink», которое можно кэшировать. Обратите внимание, что это форма поиска, поэтому она не создает ничего на сервере, просто извлекает некоторые результаты поиска. – rmcsharry

ответ

0

Благодаря комментарии от @TarynEast и другого вопроса, связанного с моим вторым редактированием, я понял, что очень спутать - так спасибо Taryn!

Это должно быть сделано в 2 отдельных действий/маршрутов, например:

post '/s', controller: :products, action: :search, as: :search_products 
    get '/s/:search', controller: :products, action: :index, as: search_results_path 

Независимо от входа пользователя, затем отправленный форме к этой поисковой деятельности.

Вот форма:

<%= form_tag(search_products_path, :method => "post", id: "search-form", name: "f1", enforce_utf8: false) do %> 
    <div class="input-group"> 
     <%= text_field_tag :search, params[:search], placeholder: "Search products", class: "form-control", name: "search" %> 
     <div class="input-group-btn"> 
     <button class="btn btn-secondary"> 
      <span class="glyphicon glyphicon-search"></span> 
     </button> 
     </div> 
    </div> 
    <% end %> 

products#search действие просто делает редирект:

def search 
    # ORIGINALLY: redirect_to "/s/#{params[:search]}" 
    redirect_to search_results_path(params[:search]) 
    end 

Тогда мы можем извлечь :search параметров и использовать его для поиска модели, например, так:

def index 
    if params[:search] && !params[:search].blank? 
     @products = Product.search params[:search] 
    ... 

и т.д.

+1

Не забудьте проверить с интересными символами (например, пробелы и слэши) в поисковом выражении. Прямо сейчас, если вы ищете «foo bar», вы получите сообщение об ошибке, так как оно будет генерировать неверный URL-адрес. Именование маршрута и использование помощника маршрута rails (например, 'redirect_to my_search_path (params [: search])' должны позаботиться об этом для вас. – gmcnaughton

+0

@gmcnaughton Большое вам спасибо за это «gotcha» :) Ответ обновлен, чтобы отразить вашего мудреца совет – rmcsharry

2

Невозможно сделать это, используя только form_tag, так как URL-адрес, который должна подавать форма, должен быть динамическим. Но это можно сделать с помощью JavaScript:

$("#search-form").submit(function(evt) { 
    var term = $("#search-form input[name='search']").val(); 
    $(this).attr('action', '/s/' + encodeURIComponent(term)); 
}); 

Это приведет к форме представления в: домене/s/[пользовательский ввод] Поиск = [пользовательский ввод]

Вы можете дополнительно предотвратить поиск? = из включенного в url, опуская атрибут name из поля (см. https://stackoverflow.com/a/3008071/157943), хотя тогда вам нужно будет дать ему id или какой-либо другой способ для фрагмента javascript выше, чтобы найти его.

+1

Спасибо, но я думаю, что есть способ без использования JS, поскольку я только что нашел связанный с этим вопрос. Мне нужно два отдельных действия контроллера и изменить форму на POST. Смотрите мое новое редактирование. – rmcsharry