2017-09-04 74 views
2

我想實現一個簡單的搜索和排序爲我的webapp。我正在關注railscast和這個railscastRails無法將未經許可的參數轉換爲散列

我爲此我使用的鏈接排序功能應用助手是:

def sortable(column, title = nil) 
     title ||= column.titleize 
     css_class = column == sort_column ? "current #{sort_direction}" : nil 
     direction = column == sort_column && sort_direction == "asc" ? "desc" : "asc" 
     link_to title, params.merge(:sort => column, :direction => direction, :page => nil), {:class => css_class} 
    end 

我在視圖中使用這些。在控制器中,我使用白名單爲:用於消毒

@listingssearch.where(:vehicletype => 'Car').order(sort_column + " " + sort_direction).paginate(:page => params[:page], :per_page => 30) 

私有方法:

private 
    def sort_column 
      Listing.column_names.include?(params) ? params[:sort] : "rateperhour" 
     end 

     def sort_direction 
      %w[asc desc].include?(params[:direction]) ? params[:direction] : "asc" 
     end 

我試着用在私有方法合併:

(Listing.column_names + params) but its not working 

對於輔助方法當我嘗試向排序鏈接提供搜索參數時出現錯誤:無法將未允許的參數轉換爲散列

它顯示的錯誤是合併

link_to title, params.merge(:sort => column, :direction => direction, :page => nil), {:class => css_class} 

周圍的otherway正常工作:

<%= bootstrap_form_for listings_path, :method => 'get' do %> 

     <%= hidden_field_tag :direction, :value => params[:direction] %> 
     <%= hidden_field_tag :sort,:value => params[:sort] %> 



     <div class= "col-sm-12 col-lg-12 col-md-12" style = "margin: auto;"> 
      <h6 style = "color:#7C064D;"><strong> PICK A DATE <span class="glyphicon glyphicon-calendar"></span></strong> 
      <%= date_field_tag :startdate, params[:startdate], placeholder: 'DATE' %>   
      </h6> 
     </div> 

     <div class= "col-sm-12 col-lg-12 col-md-12" style = "margin: auto;">  
     <p>  
      <%= text_field_tag :near, params[:near], placeholder: ' Destination' %> 
      <%= text_field_tag :radius, params[:radius], placeholder: ' Search Radius' %> 
     </p> 
     </div>  
     <div class= "col-sm-12 col-lg-12 col-md-12" style = "margin: auto;">  
     <p>  
      <%= text_field_tag :min, params[:min], placeholder: ' Minimum Rate Per Hour' %> 
      <%= text_field_tag :max, params[:max], placeholder: ' Maximum Rate Per Hour' %> 
     </p> 
     </div> 

     <div class= "col-sm-12 col-lg-12 col-md-12" style = "margin-top: 10px;">   
      <%= submit_tag "Search", class: "btn btn-info", style: "width: 40%; background-color: #E20049; border: #e20049;" %> 
      <%= link_to 'View All', root_path, class: "btn btn-info", style: "width: 40%; background-color: #E20049; border: #e20049;" %> 
     </div> 

     <!-- <div class= "col-sm-6 col-lg-6 col-md-6" style = "margin-top: 10px;">  

     </div> --> 


    <% end %> 

我的問題是如何堅持搜索PARAMS在導軌5排序輔助方法?我做錯了什麼?

回答

10

在Rails 5,ActionController::Parameters不再Hash繼承,企圖利用Hash人望而卻步與請求參數相關的方法,而不顯式地過濾它們。

作爲this pull request部分,將其移植入的Rails 5.1並部分進入的Rails 5.0,如果試圖調用的參數to_h對象而不調用permit將引發一個例外。

調用原params對象(params.merge(:sort => column, :direction => direction, :page => nil))上merge返回與相同permitted地位的新ActionController::Parameters對象(即permit還沒有被調用就可以了)。然後link_to方法最終在該對象上調用to_h,這引發了異常。

如果您知道鏈接中應允許使用哪些參數,則可以撥打permit與列出的參數。

params.permit(:param_1, :param_2).merge(:sort => column, :direction => direction, :page => nil) 
# OR 
params.merge(:sort => column, :direction => direction, :page => nil).permit(:param_1, :param_2, :sort, :direction, :page) 

如果您不知道哪些參數可以被包含在鏈接做,那麼你可以使用request.parameters.merge(...)params.to_unsafe_h.merge(...)(如this answer提到)。這些基本上在創建鏈接時規避強參數保護。默認情況下,這意味着原始請求中的任何參數也將出現在鏈接URL中。我猜想在這種特殊情況下這不是太冒險,但是如果你有其他地方的代碼不能正確消毒參數,這可能會使情況變得更糟。

+0

您是否在資源許可方法本身傳遞搜索和排序參數? –

+0

@SauravPrakash我擴展了一些答案,以包含一些示例,並對導致該異常的內容進行了輕微更正。這是否解決您的問題? – Max

+0

謝謝!明確傳遞參數將有助於防止sql注入。這將是繼續而不是request.params的正確方法。雖然兩者都有效。 –

2

,你可以嘗試使用request.parameters.merge,下面是樣本代碼上面

<%= link_to title, listings_path(request.parameters.merge({:sort => "column", :direction => "direction", :page => nil})), :class => "form-control css_class" %> 
+1

謝謝!我用你的建議,發現一個需要添加request.params.merge而不是params.merge 所以最後的返回將是:link_to title,request.params.merge({:sort => column,:direction =>方向,:page => nil}),{:class =>「css_class」}在rails 5中工作 –