Rails: сохранение параметров строки запроса GET в link_to

У меня есть обычное средство поиска в моем приложении, которое возвращает список результатов, которые можно разбивать на страницы, сортировать, просматривать с другим значением record_per_page и т.д. Каждый из этих параметров управляется параметрами в строке запроса. Упрощенный пример:

/search?q=test&page=2

Теперь скажите, что мне нужно отобразить набор ссылок, которые устанавливают значение record_per_page в 10, 20, 30. Каждая ссылка должна включать в себя существующие параметры запроса, которые могут быть очень длинными, плюс новый параметр per_page.

/search?q=test&page=2& ... &per_page=10
/search?q=test&page=2& ... &per_page=20
/search?q=test&page=2& ... &per_page=30

Есть ли простой способ сделать это с помощью только link_to helper или мне нужно как-то разобрать и воспроизвести строку запроса из предыдущего запроса?

Ответ 1

link_to 'Link', request.query_parameters.merge({:per_page => 20})

Ответ 2

link_to 'Link', params.merge({:per_page => 20})

Ответ 3

Самый простой способ объединить новые параметры с параметрами запроса и НЕ со всеми параметрами (в том числе полученными по пути) - слияние с request.query_parameters

link_to 'Search', search_path(request.query_parameters.merge({ per_page: 20 }))

В противном случае вы получите строки запроса, дублирующие параметры пути, например ?action=index&controller=products&foo=bar вместо ?foo=bar.

Ответ 4

Если вы хотите сохранить существующие параметры и не подвергать себя атакам XSS, обязательно очистите хэш параметров, оставив только параметры, которые может отправлять ваше приложение:

# inline
<%= link_to 'Link', params.slice(:sort).merge(per_page: 20) %>

 

Если вы используете его в нескольких местах, очистите параметры в контроллере:

# your_controller.rb
@params = params.slice(:sort, :per_page)

# view
<%= link_to 'Link', @params.merge(per_page: 20) %>

Ответ 5

Вы можете просто выбросить элементы хеша params в link_to. Как

link_to "some_other_link", "/search", :page => params[:page]

Ответ 6

Что насчет

<%= link_to 'Whatever', :overwrite_params => { :pear_page => 20 } %>

?

Ответ 7

Это работает, если ссылки, которые вы обрабатываете, не предоставляются вам request.params.

require 'rack/utils'                                                                                
require 'uri'                                                                                       

def modify_query url, options={}                                                                    
  uri = URI(url)                                                                                    
  query_hash = Rack::Utils.parse_query(uri.query)                                                   
  query_hash.merge!(options)                                                                        
  uri.query = Rack::Utils.build_query(query_hash)                                                   
  uri.to_s                                                                                          
end                                                                                                 

puts modify_query('/search?q=test&page=2&per_page=10', 'per_page' =>  20)                           
puts modify_query('/search?q=test&page=2', 'per_page' => 30)                                        

# Outputs                                                                                           
# /search?q=test&page=2&per_page=20                                                                 
# /search?q=test&page=2&per_page=30

Ответ 8

Немного поздно знаю..

Если вы используете это как способ фильтрации результатов поиска, посмотрите на моего помощника:)

Это автоматически удаляет все незаполненные и ненужные параметры и добавляет класс "selected", если все новые параметры уже установлены.

def search_to s, args={}

  selected = 0
  args.each do |k, v|
    selected = selected + 1 if params[k] == v.to_s || ( params[k].nil? && v.blank? )
  end

  if @search_params_base.nil?
    @search_params_base = request.parameters.clone
    @search_params_base.delete(:action)
    @search_params_base.delete(:controller)
    @search_params_base.delete(:page)
    @search_params_base.delete_if{|k, v| v.nil? || v.blank?}
    @search_params_base.delete(:utf8) if @search_params_base[:keywords].nil?
  end
  search_params = @search_params_base.merge(args)
  search_params.delete_if{|k, v| v.nil? || v.blank?}

  link_to s, search_path + '?' + search_params.to_param, :class => selected == args.length ? 'selected' : nil
end

Вы можете просто использовать это в своем представлении:

search_to '$80 to $110', :price => 80..110

Или в вашем случае:

search_to '30 per page', :page => params[:page], :per_page => 30