Rails 无法将不允许的参数转换为散列
Rails Unable to convert unpermitted parameters to hash
我正在尝试为我的 webapp 实现一个简单的搜索和排序。我正在关注 railscast and this railscast。
我用作 link 的可排序函数的应用程序助手是:
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:无法将不允许的参数转换为散列
显示合并错误
link_to title, params.merge(:sort => column, :direction => direction, :page => nil), {:class => css_class}
反之亦然:
<%= 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 %>
我的问题是如何在 rails 5 的排序辅助方法中保留搜索参数?我做错了什么?
您可以尝试使用 request.parameters.merge,下面是您上面代码的示例
<%= link_to title, listings_path(request.parameters.merge({:sort => "column", :direction => "direction", :page => nil})), :class => "form-control css_class" %>
在Rails5中,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
returns 具有相同 permitted
状态的新 ActionController::Parameters
对象 (也就是说,permit
还没有被调用)。 link_to
方法最终调用该对象的 to_h
,这引发了异常。
如果您知道 link 中应该允许哪些参数,您可以使用列出的参数调用 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)
如果您不知道 link 中可以包含哪些参数,则可以调用 request.parameters.merge(...)
(如 中所述)或 params.to_unsafe_h.merge(...)
.然而,正如评论中所指出的,当结果被传递给 link_to
时,这是一个安全风险,因为像 host
这样的参数将被解释为 link 的实际主机而不是一个查询参数。在 link_to
中还有其他几个键也有特殊含义(url_for
接受的所有内容,再加上 :method
),所以这通常是一种冒险的方法。
我相信如果你通过专栏允许它应该让你再次工作!
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
你可以使用这个技巧:
params.to_enum.to_h
我认为 rails 开发人员在知道这是使用未经许可的参数的方式时会对其进行限制。 :)
您也可以通过 params.permit!
覆盖,但这可能存在安全风险,因此请谨慎使用。
因为没有人提出这个建议。所以这是我们可以使用 params.to_unsafe_hash
的一种方法,它将强参数转换为散列。
例如:
(byebug) values
<ActionController::Parameters {"country"=>"RU", "city"=>"Moscow", "street"=>"1 First Street", "zip"=>"123456"} permitted: false>
(byebug) values.to_unsafe_hash
{"country"=>"RU", "city"=>"Moscow", "street"=>"1 First Street", "zip"=>"123456"}
我正在尝试为我的 webapp 实现一个简单的搜索和排序。我正在关注 railscast and this railscast。
我用作 link 的可排序函数的应用程序助手是:
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:无法将不允许的参数转换为散列
显示合并错误
link_to title, params.merge(:sort => column, :direction => direction, :page => nil), {:class => css_class}
反之亦然:
<%= 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 %>
我的问题是如何在 rails 5 的排序辅助方法中保留搜索参数?我做错了什么?
您可以尝试使用 request.parameters.merge,下面是您上面代码的示例
<%= link_to title, listings_path(request.parameters.merge({:sort => "column", :direction => "direction", :page => nil})), :class => "form-control css_class" %>
在Rails5中,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
returns 具有相同 permitted
状态的新 ActionController::Parameters
对象 (也就是说,permit
还没有被调用)。 link_to
方法最终调用该对象的 to_h
,这引发了异常。
如果您知道 link 中应该允许哪些参数,您可以使用列出的参数调用 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)
如果您不知道 link 中可以包含哪些参数,则可以调用 request.parameters.merge(...)
(如 params.to_unsafe_h.merge(...)
.然而,正如评论中所指出的,当结果被传递给 link_to
时,这是一个安全风险,因为像 host
这样的参数将被解释为 link 的实际主机而不是一个查询参数。在 link_to
中还有其他几个键也有特殊含义(url_for
接受的所有内容,再加上 :method
),所以这通常是一种冒险的方法。
我相信如果你通过专栏允许它应该让你再次工作!
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
你可以使用这个技巧:
params.to_enum.to_h
我认为 rails 开发人员在知道这是使用未经许可的参数的方式时会对其进行限制。 :)
您也可以通过 params.permit!
覆盖,但这可能存在安全风险,因此请谨慎使用。
因为没有人提出这个建议。所以这是我们可以使用 params.to_unsafe_hash
的一种方法,它将强参数转换为散列。
例如:
(byebug) values
<ActionController::Parameters {"country"=>"RU", "city"=>"Moscow", "street"=>"1 First Street", "zip"=>"123456"} permitted: false>
(byebug) values.to_unsafe_hash
{"country"=>"RU", "city"=>"Moscow", "street"=>"1 First Street", "zip"=>"123456"}