Ruby-on-rails 强参数允许嵌套属性的所有属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17810838/
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-02 22:22:43  来源:igfitidea点击:

strong parameters permit all attributes for nested attributes

ruby-on-railsrubyruby-on-rails-3.2ruby-on-rails-4strong-parameters

提问by AnkitG

Is there a way in strong parametersto permit all attributes of a nested_attributes model? Here is a sample code.

有没有办法在强参数中允许nested_attributes 模型的所有属性?这是一个示例代码。

class Lever < ActiveRecord::Base
 has_one :lever_benefit
 accepts_nested_attributes_for :lever_benefit
end

class LeverBenefit < ActiveRecord::Base
  # == Schema Information
  #  id          :integer          not null, primary key
  #  lever_id    :integer
  #  explanation :text
end

For lever strong parameters i am writing currently this

对于杠杆强参数,我目前正在写这个

def lever
 params.require(:lever).permit(:name,:lever_benefit_attributes => [:lever_id, :explanation])
end

Is there a way for nested attributesi can write to permit all attributes without explicitly giving the attributes name like lever_idand explanation?

有没有办法让我可以编写嵌套属性来允许所有属性,而无需明确给出属性名称,例如lever_idexplanation

Note: Please don't get confused with this question with permit!or permit(:all)this is for permitting all for nested attributes

注意:请不要与此问题混淆,permit!或者permit(:all)这是为了允许所有嵌套属性

采纳答案by Damien MATHIEU

The whole point of strong parameters is in its name: make your input parameters strong.
Permitting all the parameters would be a very bad idea, as it would permit anyone to insert values you don't necessarily want to be updated by your users.

强参数的全部意义在于其名称:使您的输入参数强。
允许所有参数将是一个非常糟糕的主意,因为它会允许任何人插入您不一定希望由您的用户更新的值。

In the example you give, you mention the two parameters you currently need to provide:
[:lever_id, :explanation].

在您提供的示例中,您提到了当前需要提供的两个参数:
[:lever_id, :explanation].

If you permitted all the parameters, it would be possible for somebody to change any other value.
created_at, or lever_idfor example.

如果您允许所有参数,则有人可以更改任何其他值。
created_at,或者lever_id例如。

This would definitely be a security issue and this is why you should not do it.
Explicitely specifying all your attributes might seem boring when you do it.
But this is necessary to keep your application secure.

这肯定是一个安全问题,这就是为什么你不应该这样做。
当你这样做时,明确指定你的所有属性可能看起来很无聊。
但这对于确保您的应用程序安全是必要的。

Edit: For people downvoting this. This may not be the answer you're looking for, but it is the answer you need.
Whitelisting all nested attributes is a huge security flaw that strong params is trying to protect you with, and you're removing it.
Take a look at what lead to building strong_params, and how not using it can be bad for you: https://gist.github.com/peternixey/1978249

编辑:对于那些反对这一点的人。这可能不是您正在寻找的答案,但却是您需要的答案。
将所有嵌套属性列入白名单是一个巨大的安全漏洞,强参数试图保护您,而您正在删除它。
看看是什么导致了构建 strong_params,以及不使用它对你有什么危害:https://gist.github.com/peternixey/1978249

回答by tfischbach

The only situation I have encountered where permitting arbitrary keys in a nested params hash seems reasonable to me is when writing to a serialized column. I've managed to handle it like this:

我遇到的唯一允许嵌套参数哈希中的任意键对我来说似乎合理的情况是写入序列化列时。我设法像这样处理它:

class Post
  serialize :options, JSON
end

class PostsController < ApplicationController
  ...

  def post_params
    all_options = params.require(:post)[:options].try(:permit!)
    params.require(:post).permit(:title).merge(:options => all_options)
  end
end

trymakes sure we do not require the presents of an :optionskey.

try确保我们不需要:options钥匙的礼物。

回答by nothing-special-here

Actually there is a way to just white-list all nested parameters.

实际上有一种方法可以将所有嵌套参数列入白名单。

params.require(:lever).permit(:name).tap do |whitelisted|
  whitelisted[:lever_benefit_attributes ] = params[:lever][:lever_benefit_attributes ]
end

This method has advantage over other solutions. It allows to permit deep-nested parameters.

这种方法优于其他解决方案。它允许允许深度嵌套的参数。

While other solutions like:

而其他解决方案如:

nested_keys = params.require(:lever).fetch(:lever_benefit_attributes, {}).keys
params.require(:lever).permit(:name,:lever_benefit_attributes => nested_keys)

Don't.

别。



Source:

来源:

https://github.com/rails/rails/issues/9454#issuecomment-14167664

https://github.com/rails/rails/issues/9454#issuecomment-14167664

回答by severin

First, make sure that you really want to allow all values in a nested hash. Read through Damien MATHIEU's answerto understand the potential opening of security holes...

首先,确保您确实希望允许嵌套散列中的所有值。通读Damien MATHIEU 的回答,了解潜在的安全漏洞...

If you still need/want to allow all values in a hash (there are perfectly valid use cases for this, e.g. storing unstructured, user-provided metadata for a record), you can achieve it using the following bits of code:

如果您仍然需要/希望允许散列中的所有值(有完全有效的用例,例如存储非结构化的、用户提供的记录元数据),您可以使用以下代码位实现它:

def lever_params
  nested_keys = params.require(:lever).fetch(:lever_benefit_attributes, {}).keys
  params.require(:lever).permit(:name,:lever_benefit_attributes => nested_keys)
end

Note: This is very similar to tf.'s answerbut a bit more elegant since you will not get any Unpermitted parameters: lever_benefit_attributeswarnings/errors.

注意:这与tf. 的答案非常相似,但更优雅一些,因为您不会收到任何Unpermitted parameters: lever_benefit_attributes警告/错误。

回答by seufagner

try

尝试

params.require(:lever).permit(:name, leave_benefit_attributes: LeaveBenefit.attribute_names.collect { |att| att.to_sym })

回答by Jungong Shi

I am surprised at no one suggested this:

我很惊讶没有人提出这个建议:

params.require(:lever).permit(:name,:lever_benefit_attributes => {})