Rails: сохранение параметров строки запроса GET в link_to - PullRequest
45 голосов
/ 21 сентября 2010

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

/search?q=test&page=2

Теперь скажите, что мне нужно отобразить набор ссылок, для которых значение records_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, или мне нужно как-то проанализировать и воспроизвести строку запроса из предыдущего запроса?

Ответы [ 8 ]

63 голосов
/ 21 сентября 2010
link_to 'Link', request.query_parameters.merge({:per_page => 20})
22 голосов
/ 13 ноября 2010
link_to 'Link', params.merge({:per_page => 20})
18 голосов
/ 06 января 2015

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

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

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

3 голосов
/ 10 мая 2014

Если вы хотите сохранить существующие параметры и не подвергать себя атакам 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) %>
2 голосов
/ 21 сентября 2010

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

link_to "some_other_link", "/search", :page => params[:page]
1 голос
/ 19 июня 2012

Это работает, если ссылки, которые вы обрабатываете, не переданы вам 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
1 голос
/ 21 сентября 2010

А как же

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

0 голосов
/ 06 июня 2011

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

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

Это автоматически удаляет все пустые и ненужные параметры и добавляет класс «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
...