我遇到了一个奇怪的问题。
undefined method `values' for #<ActionController::Parameters:0x007fb06f6b2728>
是我得到的错误,当我将变量分配给param哈希,并尝试获取它的值。
attributes = params[:line_item][:line_item_attributes_attributes] || {}
attributes.values
参数看起来像哈希的散列:
{"0"=>{"product_attribute_id"=>"4"}, "1"=>{"product_attribute_id"=>"7"}}
现在,当我在控制台中执行此操作并将其分配给变量属性时,它可以完美地运行。所以我很难理解这里不起作用的东西 - 以及如何使它发挥作用。
答案 0 :(得分:47)
看看this。非常奇怪,因为ActionController::Parameters
是Hash的子类,您可以使用params哈希上的to_h
方法将其directly转换为哈希。
但to_h
仅适用于列入白名单的参数,因此您可以执行以下操作:
permitted = params.require(:line_item).permit(: line_item_attributes_attributes)
attributes = permitted.to_h || {}
attributes.values
但如果你不想白名单,那么你只需要使用to_unsafe_h
方法。
我对这个问题非常好奇,所以我开始研究,现在你澄清了你正在使用Rails 5,这就是问题的原因,正如@tillmo在4.x等Rails的稳定版本中说的那样, ActionController::Parameters
是Hash的子类,所以它确实应该响应values
方法,但是在Rails 5中ActionController::Parameters
现在返回一个Object而不是一个Hash < / p>
注意:这不会影响访问params哈希中的密钥,例如params[:id]
。您可以查看实施此更改的Pull Request。
要访问对象中的参数,您可以将to_h
添加到参数:
params.to_h
如果我们查看to_h
中的ActionController::Parameters
方法,我们可以看到它在将参数转换为哈希之前检查参数是否被允许。
# 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
访问参数,您需要首先允许参数,然后在对象上调用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
答案 1 :(得分:8)
因为在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
但要注意使用它!您允许所有可能包含可能损害您代码的未知参数的参数。
答案 2 :(得分:1)
我认为发生的事情如下:
在控制台中,您正在使用名为attributes
的简单哈希。作为哈希,控制台中的attributes
参数名为values
a valid instance method。
在你的rails app中,params hash不再是一个简单的哈希。它是ActionController::Parameters
类的一个实例。作为该类的一个实例,它没有名为values
的实例方法,但它确实有an instance method called to_h
&amp; to_unsafe_h
,这将实现您的目标。在您的参数上调用to_h
后,您可以调用values
方法。