Rails无法将未经许可的参数转换为哈希值

我正在尝试为我的webapp实现一个简单的搜索和排序。 我正在关注railscast和这个railscast 。

我作为链接使用的可排序函数的应用程序帮助程序是:

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 

我尝试在私有方法中使用merge:

 (Listing.column_names + params) but its not working 

对于帮助器方法, 当我尝试向排序链接提供搜索参数时,我收到错误 :无法将未经许可的参数转换为哈希

它显示错误是合并

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

其他方面工作正常:

  'get' do %>  params[:direction] %>  params[:sort] %> 
PICK A DATE

<!--
-->

我的问题是如何在rails 5中的sort helper方法中持久搜索params? 我做错了什么?

在Rails 5中, ActionController::Parameters不再inheritanceHash ,试图阻止人们在请求参数上使用与Hash相关的方法而不显式过滤它们。

作为此拉取请求的一部分,如果您尝试在参数对象上调用to_h而不调用permit ,则会将其移植到Rails 5.1中并部分移植到Rails 5.0中。

在原始params对象上调用mergeparams.merge(:sort => column, :direction => direction, :page => nil) )返回一个具有相同permitted状态的新ActionController::Parameters对象(即, permit没被召唤过来)。 然后, link_to方法最终在该对象上调用to_h ,从而引发exception。

如果您知道链接中应允许哪些参数,则可以使用列出的参数调用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(...) 。 在创建链接时,这两者基本上都绕过了强参数保护。 默认情况下,这意味着原始请求中的任何参数也会出现在链接URL中。 我想在这种特殊情况下风险并不大,但如果你在其他地方有代码没有正确清理参数,这可能会使情况变得更糟。

您可以尝试使用request.parameters.merge,下面是上面代码的示例

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

我相信如果你通过专栏允许它应该让你再次工作!

 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.permit(column).merge(sort: column, direction: direction, page: nil), { class: css_class } end