可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a typical search facility in my app which returns a list of results that can be paginated, sorted, viewed with a different records_per_page value, etc. Each of these options is controlled by parameters in the query string. A simplified example:
/search?q=test&page=2
Now say I need to display a set of links that set records_per_page value to 10, 20, 30. Each link must include the existing query parameters, which can be a very long set, plus a new per_page parameter.
/search?q=test&page=2& ... &per_page=10
/search?q=test&page=2& ... &per_page=20
/search?q=test&page=2& ... &per_page=30
Is there an easy way to do it with just link_to helper or I need to parse and reproduce the query string from previous request somehow?
回答1:
link_to 'Link', request.query_parameters.merge({:per_page => 20})
回答2:
link_to 'Link', params.merge({:per_page => 20})
回答3:
The simplest way to merge the new params with the query parameters and NOT with all parameters (including those obtained through the path) is to merge with request.query_parameters
link_to 'Search', search_path(request.query_parameters.merge({ per_page: 20 }))
Otherwise you end up with query strings duplicating the path parameters, for example ?action=index&controller=products&foo=bar
instead of ?foo=bar
.
回答4:
If you want to keep existing params and not expose yourself to XSS attacks, be sure to clean the params hash, leaving only the params that your app can be sending:
# inline
<%= link_to 'Link', params.slice(:sort).merge(per_page: 20) %>
If you use it in multiple places, clean the params in the controller:
# your_controller.rb
@params = params.slice(:sort, :per_page)
# view
<%= link_to 'Link', @params.merge(per_page: 20) %>
回答5:
You can just throw elements of the params
hash at link_to
. Like
link_to "some_other_link", "/search", :page => params[:page]
回答6:
What about
<%= link_to 'Whatever', :overwrite_params => { :pear_page => 20 } %>
?
回答7:
This works if the links you are processing aren't given to you by 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:
A bit late i know..
If your using this as a way to filter search results have a look at my helper :)
This automagicly removes all blank and unneeded params and add the class "selected" if all of it's new params were already set.
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
You can then just use this in your view:
search_to '$80 to $110', :price => 80..110
Or in your case:
search_to '30 per page', :page => params[:page], :per_page => 30