看看this.非常奇怪,因为ActionController::Parameters
是Hash的一个子类,所以可以使用params Hash上的to_h
方法将其directly转换为Hash.
但是,to_h
只适用于白名单参数,因此您可以执行以下操作:
permitted = params.require(:line_item).permit(: line_item_attributes_attributes)
attributes = permitted.to_h || {}
attributes.values
但是如果你不想将其列入白名单,那么你只需要使用to_unsafe_h
方法.
Update
我对这个问题很好奇,所以我开始研究,现在你澄清了你正在使用Rails 5,这就是这个问题的原因,正如@tillmo在Rails 4的稳定版本中所说的.x、 ActionController::Parameters
是Hash的一个子类,因此它确实应该响应values
方法however in Rails 5 100 now returns an Object instead of a Hash
Note:这不会影响访问参数散列中的键,比如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
应用程序总是有一个许可证.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