【问题标题】:Rails: Preserving GET query string parameters in link_toRails:在 link_to 中保留 GET 查询字符串参数
【发布时间】:2011-04-15 07:33:21
【问题描述】:

我的应用程序中有一个典型的搜索工具,它返回一个可以分页、排序、使用不同的 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 帮助程序,或者我需要以某种方式解析和重现先前请求中的查询字符串?

【问题讨论】:

标签: ruby-on-rails parameters routing helpers


【解决方案1】:
link_to 'Link', request.query_parameters.merge({:per_page => 20})

【讨论】:

  • 这会添加一些“额外”参数,例如 controlleraction
  • 但是你可以通过使用request.query_parameters而不是request.parameters来避免这种情况
  • 如果您的查询参数需要关联数组或嵌套哈希,请使用 deep_merge
【解决方案2】:

将新参数与查询参数而不是所有参数(包括通过路径获得的参数)合并的最简单方法是与 request.query_parameters

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

否则,您最终会得到重复路径参数的查询字符串,例如 ?action=index&controller=products&foo=bar 而不是 ?foo=bar

【讨论】:

    【解决方案3】:

    如果您想保留现有参数并且不让自己受到 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) %>
    

    【讨论】:

      【解决方案4】:

      如果您正在处理的链接不是由 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
      

      【讨论】:

        【解决方案5】:

        我知道有点晚了..

        如果您将其用作过滤搜索结果的一种方式,请查看我的助手 :)

        这会自动删除所有空白和不需要的参数,如果所有新参数都已设置,则添加“选定”类。

        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
        

        【讨论】:

          【解决方案6】:
          link_to 'Link', params.merge({:per_page => 20})
          

          【讨论】:

            【解决方案7】:

            怎么样

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

            ?

            【讨论】:

            • 这看起来就像我要找的一样。但是它在 Rails 3 中已被弃用。link_to 'link', request.parameters.merge({:per_page => 20}) 为我工作。
            • rails 3.2+ 的方法是什么?
            【解决方案8】:

            您可以将params 哈希的元素扔到link_to。喜欢

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

            【讨论】:

              猜你喜欢
              • 2012-08-02
              • 2013-07-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-02-11
              • 1970-01-01
              相关资源
              最近更新 更多