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

Seb*_*nes 29 ruby-on-rails ruby-on-rails-5

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

undefined method `values' for #<ActionController::Parameters:0x007fb06f6b2728>
Run Code Online (Sandbox Code Playgroud)

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

attributes = params[:line_item][:line_item_attributes_attributes] || {}
attributes.values
Run Code Online (Sandbox Code Playgroud)

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

{"0"=>{"product_attribute_id"=>"4"}, "1"=>{"product_attribute_id"=>"7"}}
Run Code Online (Sandbox Code Playgroud)

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

Sso*_*esS 52

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

但是to_h只能使用列入白名单的参数,因此您可以执行以下操作:

permitted = params.require(:line_item).permit(: line_item_attributes_attributes)
attributes = permitted.to_h || {}
attributes.values
Run Code Online (Sandbox Code Playgroud)

但如果您不想白名单,那么您只需要使用该to_unsafe_h方法.

更新

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

注意:这不会影响访问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
Run Code Online (Sandbox Code Playgroud)

例如

def do_something_with_params
  params.slice(:param_1, :param_2)
end
Run Code Online (Sandbox Code Playgroud)

哪个会回归:

{ :param_1 => "a", :param_2 => "2" }
Run Code Online (Sandbox Code Playgroud)

但现在这将返回一个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
Run Code Online (Sandbox Code Playgroud)

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

def do_something_with_params
  params.to_unsafe_h.slice(:param_1, :param_2)
end
Run Code Online (Sandbox Code Playgroud)

有一种方法可以始终允许来自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)
Run Code Online (Sandbox Code Playgroud)

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

def do_something_with_params
  params.slice("param_1", "param_2").to_h
end
Run Code Online (Sandbox Code Playgroud)

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

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

资料来源:eileen.codes


Abh*_*bhi 9

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

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

*** ActionController::UnfilteredParameters Exception: unable to convert 
unpermitted parameters to hash
Run Code Online (Sandbox Code Playgroud)

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

parameters = params.permit(params.keys).to_h
Run Code Online (Sandbox Code Playgroud)

但要注意使用它!您允许所有可能包含可能损害您的代码的未知参数的参数.