Ruby-on-rails Rails 5:无法从参数中检索哈希值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34949505/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 00:21:55  来源:igfitidea点击:

Rails 5: unable to retrieve hash values from parameter

ruby-on-railsruby-on-rails-5

提问by Sebastian Jennings Almnes

I'm running into a strange issue.

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

undefined method `values' for #<ActionController::Parameters:0x007fb06f6b2728>

is the error I get, when I assign a variable to a param hash, and try to get it's values.

是我得到的错误,当我将一个变量分配给一个 param 散列并尝试获取它的值时。

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

the parameter looks like this a hash of hashes:

参数看起来像这样一个散列的散列:

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

now when I do this in console and assign that to a variable attributes it works flawlessly. So I'm struggling to understand what isn't working here - and how to make it work.

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

回答by svelandiag

take a look to this. Very weird since ActionController::Parametersis a subclass of Hash, you can convert it directlyto a hash using the to_hmethod on the params hash.

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

However to_honly will work with whitelisted params, so you can do something like:

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

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

But if instead you do not want to whitelist then you just need to use the to_unsafe_hmethod.

但是,如果您不想将其列入白名单,那么您只需要使用该to_unsafe_h方法。

Update

更新

I was very curious about this issue, so I started researching, and now that you clarified that you are using Rails 5, well that's the cause of this issue, as @tillmo said in stable releases of Rails like 4.x, ActionController::Parametersis a subclass of Hash, so it should indeed respond to the valuesmethod, however in Rails 5 ActionController::Parametersnow returns an Object instead of a Hash

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

Note: this doesn't affect accessing the keys in the params hash like params[:id]. You can view the Pull Requestthat implemented this change.

注意:这不会影响访问 params 散列中的键,如params[:id]. 您可以查看实现此更改的拉取请求

To access the parameters in the object you can add to_hto the parameters:

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

params.to_h

params.to_h

If we look at the to_hmethod in ActionController::Parameterswe can see it checks if the parameters are permitted before converting them to a hash.

如果我们查看 中的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

for example example

例如例子

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

Which would return:

哪个会返回:

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

But now that will return an ActionController::Parametersobject.

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

Calling to_hon this would return an empty hash because param_1 and param_2 aren't permitted.

调用to_h它会返回一个空的哈希值,因为 param_1 和 param_2 是不允许的。

To get access to the params from ActionController::Parameters, you need to first permit the params and then call to_hon the object

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

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

The above would return a hash with the params you just permitted, but if you do not want to permit the params and want to skip that step there is another way using to_unsafe_hashmethod:

以上将返回一个包含您刚刚允许的参数的哈希值,但如果您不想允许参数并想跳过该步骤,则还有另一种使用to_unsafe_hash方法的方法:

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

There is a way of always permit the params from a configuration from application.rb, if you want to always allow certain parameters you can set a configuration option. Note: this will return the hash with string keys, not symbol keys.

有一种方法可以始终允许来自 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)

Now you can access the params like:

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

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

Note that now the keys are strings and not symbols.

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

Hope this help you to understand the root of your issue.

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

Source: eileen.codes

资料来源:eileen.codes

回答by Abhi

Since in Rails 5 params are of class 'ActionController::Parameters'

因为在 Rails 5 参数是类'ActionController::Parameters'

If you do params.to_h you will get the following error.

如果你做 params.to_h 你会得到以下错误。

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

You can do as follows to get the params as Hash format:

您可以执行以下操作以获取 Hash 格式的参数:

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

But beware of using this! You are permitting all the params which may include unknown params that can harm your code.

但要小心使用这个!您正在允许所有可能包含可能损害您的代码的未知参数的参数。

回答by BigRon

I think what's happening is the following:

我认为正在发生的事情如下:

In a console you are working with a simple hash called attributes. As a hash the attributesparameter in the console has a valid instance methodcalled values.

在控制台中,您正在使用一个名为attributes. 作为散列,attributes控制台中的参数有一个有效的实例方法,称为values.

In your rails app the params hash is not a simple hash any more. It is an instance of the ActionController::Parametersclass. As an instance of that class it does not have an instance method called values, but it does have an instance method calledto_h& to_unsafe_h, which would accomplish your goals. After calling to_hon your parameters you can call the valuesmethod.

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

回答by okay56k

Word to the wise: if you're using link_to_sortedfrom the sortedgem it breaks views in Rails 5.

聪明人的话:如果你正在使用link_to_sorted排序宝石它打破Rails中5次。