J'ai une fonction de recherche typique dans mon application qui renvoie une liste de résultats qui peuvent être paginés, triés, affichés avec une valeur records_per_page différente, etc. Chacune de ces options est contrôlée par des paramètres dans la chaîne de requête. Un exemple simplifié:
/search?q=test&page=2
Supposons maintenant que je dois afficher un ensemble de liens qui définissent la valeur records_per_page sur 10, 20, 30. Chaque lien doit inclure les paramètres de requête existants, qui peuvent être un ensemble très long, plus un nouveau paramètre 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
Existe-t-il un moyen facile de le faire avec simplement link_to helper ou j'ai besoin d'analyser et de reproduire la chaîne de requête de la demande précédente d'une manière ou d'une autre?
link_to 'Link', request.query_parameters.merge({:per_page => 20})
link_to 'Link', params.merge({:per_page => 20})
La manière la plus simple de fusionner les nouveaux paramètres avec les paramètres de requête et NON avec tous les paramètres (y compris ceux obtenus via le chemin d'accès) est de fusionner avec request.query_parameters
link_to 'Search', search_path(request.query_parameters.merge({ per_page: 20 }))
Sinon, vous vous retrouvez avec des chaînes de requête dupliquant les paramètres de chemin, par exemple ?action=index&controller=products&foo=bar
au lieu de ?foo=bar
.
Si vous souhaitez conserver les paramètres existants et ne pas vous exposer aux attaques XSS, assurez-vous de nettoyer le hachage des paramètres, en ne laissant que les paramètres que votre application peut envoyer:
# inline
<%= link_to 'Link', params.slice(:sort).merge(per_page: 20) %>
Si vous l'utilisez à plusieurs endroits, nettoyez les paramètres du contrôleur:
# your_controller.rb
@params = params.slice(:sort, :per_page)
# view
<%= link_to 'Link', @params.merge(per_page: 20) %>
Vous pouvez simplement lancer des éléments du hachage params
sur link_to
. Comme
link_to "some_other_link", "/search", :page => params[:page]
Cela fonctionne si les liens que vous traitez ne vous sont pas fournis par 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
Qu'en est-il de
<%= link_to 'Whatever', :overwrite_params => { :pear_page => 20 } %>
?
Un peu tard je sais ..
Si vous utilisez cela comme un moyen de filtrer les résultats de recherche, jetez un œil à mon aide :)
Cela supprime automatiquement tous les paramètres vides et inutiles et ajoute la classe "sélectionnée" si tous ses nouveaux paramètres ont déjà été définis.
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
Vous pouvez ensuite simplement utiliser ceci dans votre vue:
search_to '$80 to $110', :price => 80..110
Ou dans votre cas:
search_to '30 per page', :page => params[:page], :per_page => 30