Rails 5:无法从参数中检索哈希值

我遇到了一个奇怪的问题。

undefined method `values' for # 

是我得到的错误,当我将变量分配给param哈希,并尝试获取它的值。

 attributes = params[:line_item][:line_item_attributes_attributes] || {} attributes.values 

该参数看起来像哈希的散列:

 {"0"=>{"product_attribute_id"=>"4"}, "1"=>{"product_attribute_id"=>"7"}} 

现在当我在控制台中执行此操作并将其分配给变量属性时,它可以完美地工作。 所以我很难理解这里不起作用的东西 – 以及如何让它发挥作用。

看看这个 。 非常奇怪,因为ActionController::Parameters是Hash的子类,您可以使用params哈希上的to_h方法将其直接转换为哈希。

但是to_h只适用于列入白名单的params,因此您可以执行以下操作:

 permitted = params.require(:line_item).permit(: line_item_attributes_attributes) attributes = permitted.to_h || {} attributes.values 

但如果你不想白名单,那么你只需要使用to_unsafe_h方法。

更新

我对这个问题非常好奇,所以我开始研究,现在你澄清了你正在使用Rails 5,这就是问题的原因,正如@tillmo在稳定版本的Rails中说的那样,如4.x, ActionController::Parameters是Hash的子类,所以它确实应该响应values方法, 但是在Rails 5中ActionController::Parameters现在返回一个Object而不是一个Hash

注意 :这不会影响访问params散列中的键,如params[:id] 。 您可以查看实施此更改的Pull Request 。

要访问对象中的参数,可以将to_h添加到参数中:

params.to_h

如果我们在ActionController::Parameters中查看to_h方法,我们可以看到它在将参数转换为哈希之前检查参数是否被允许。

 # actionpack/lib/action_controller/metal/strong_parameters.rb def to_h if permitted? @parameters.to_h else slice(*self.class.always_permitted_parameters).permit!.to_h end end 

例如

 def do_something_with_params params.slice(:param_1, :param_2) end 

哪会回来:

 { :param_1 => "a", :param_2 => "2" } 

但现在这将返回一个ActionController::Parameters对象。

在此调用to_h将返回空哈希,因为不允许使用param_1和param_2。

要从ActionController::Parameters访问params,您需要首先允许params,然后在对象上调用to_h

 def do_something_with_params params.permit([:param_1, :param_2]).to_h end 

上面会返回一个你刚刚允许的参数的哈希,但是如果你不想允许参数并希望跳过这一步,那么使用to_unsafe_hash方法还有另一种方法:

 def do_something_with_params params.to_unsafe_h.slice(:param_1, :param_2) end 

有一种方法可以始终允许来自application.rb的配置中的参数,如果要始终允许某些参数,则可以设置配置选项。 注意:这将使用字符串键返回哈希值,而不是符号键。

 #controller and action are parameters that are always permitter by default, but you need to add it in this config. config.always_permitted_parameters = %w( controller action param_1 param_2) 

现在您可以访问以下参数:

 def do_something_with_params params.slice("param_1", "param_2").to_h end 

请注意,现在键是字符串而不是符号。

希望这有助于您了解问题的根源。

资料来源: eileen.codes

因为在Rails 5中,params属于’ActionController :: Parameters’类

如果你执行params.to_h,你将收到以下错误。

 *** ActionController::UnfilteredParameters Exception: unable to convert unpermitted parameters to hash 

您可以执行以下操作以将参数设置为哈希格式:

 parameters = params.permit(params.keys).to_h 

我认为发生的事情如下:

在控制台中,您正在使用名为attributes的简单哈希。 作为哈希,控制台中的attributes参数具有名为values 的有效实例方法 。

在你的rails app中,params hash不再是一个简单的哈希。 它是ActionController::Parameters类的一个实例。 作为该类的一个实例,它没有名为values的实例方法,但它确实有一个名为 to_hto_unsafe_h 的实例方法 ,它可以实现您的目标。 在调用to_h参数后,您可以调用values方法。

明智的话:如果你从排序的 gem中使用link_to_sorted它会破坏Rails 5中的视图。