看看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 在 Rails 4.x 等稳定版本中所说, ActionController::Parameters 是 Hash 的子类,所以它确实应该响应 values 方法,但是在 Rails 5 中 ActionController::Parameters 现在返回一个 Object 而不是一个 Hash
注意:这不会影响访问参数哈希中的键,例如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 访问参数,您需要先允许这些参数,然后在对象上调用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