简体   繁体   English

强参数允许嵌套属性的所有属性

[英]strong parameters permit all attributes for nested attributes

Is there a way in strong parameters to permit all attributes of a nested_attributes model ?有没有办法在强参数中允许nested_attributes 模型的所有属性? Here is a sample code.这是一个示例代码。

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 attributes i can write to permit all attributes without explicitly giving the attributes name like lever_id and explanation ?有没有办法让我可以编写嵌套属性来允许所有属性,而无需明确给出属性名称,如lever_idexplanation

Note : Please don't get confused with this question with permit!注意:请不要与permit!混淆这个问题permit! or permit(:all) this is for permitting all for nested attributespermit(:all)这用于允许所有嵌套属性

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

try makes sure we do not require the presents of an :options key. try确保我们不需要:options键的礼物。

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

First, make sure that you really want to allow all values in a nested hash.首先,确保您确实希望允许嵌套散列中的所有值。 Read through Damien MATHIEU's answer to 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, eg 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 answer but a bit more elegant since you will not get any Unpermitted parameters: lever_benefit_attributes warnings/errors.注意:这与tf. 的答案非常相似,但更优雅一些,因为您不会得到任何Unpermitted parameters: lever_benefit_attributes警告/错误。

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

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

尝试

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

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_id for 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM