2010-09-21 6 views
41

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 paramètres dans la chaîne de requête. Un exemple simplifié:Rails: Préserver les paramètres de la chaîne de requête GET dans link_to

/search?q=test&page=2 

disent Maintenant, je dois montrer un ensemble de liens qui définissent la valeur records_per_page à 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 

est-il un moyen facile de le faire avec juste link_to aide ou je dois analyser et reproduire la chaîne de requête de demande précédente en quelque sorte?

+0

duplication possible de [Ajouter des paramètres de chaîne de caractères à lier \ _to] (http://stackoverflow.com/questions/2695538/add-querystring-parameters-to-link-to) –

Répondre

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

Ceci ajoute des paramètres 'supplémentaires' comme 'controller' et' action'. – kikito

+13

Mais vous pouvez éviter cela en utilisant 'request.query_parameters' au lieu de' request.parameters' – kikito

+1

utilisez 'deep_merge' si vos paramètres de requête nécessitent des tableaux associés ou un hachage imbriqué – twnaing

2

Vous pouvez simplement lancer des éléments du hachage params au link_to. Comme

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

Qu'en est-

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

?

+1

Cela ressemble à ce que je cherchais . Cependant, il est obsolète dans Rails 3. link_to 'link', request.parameters.merge ({: per_page => 20}) a fonctionné pour moi. – Vincent

+1

Quels sont les rails 3.2 + façon de faire cela? – coudron

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

Un peu en retard je sais ..

si vous utilisez cela comme un moyen de filtrer les résultats de recherche ont un oeil à mon aide :)

Cette supprime toutes vierges automatiquement disponibles et params inutiles et ajoutez la classe "selected" 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 simplement utiliser 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 
1

Cela fonctionne si les liens que vous traitez ne sont pas donnés pour vous 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 
3

Si vous voulez garder params existants et ne pas vous exposer à des attaques XSS, assurez-vous de nettoyer le hachage params, ne laissant que les params que votre application peut enverrez:

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

 

Si vous l'utilisez dans plusieurs endroits, nettoyer les params du contrôleur:

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

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

La méthode la plus simple pour fusionner les nouveaux paramètres avec les paramètres de requête et PAS avec tous les paramètres (y compris ceux obtenus via le chemin) est de fusionner avec la requête .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 dupliquer les paramètres de chemin, par exemple ?action=index&controller=products&foo=bar au lieu de ?foo=bar.

+0

Cela devrait être la réponse acceptée. – Agis

Questions connexes