35

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

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

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

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

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

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

4

6 回答 6

58

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

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确保我们不需要:options钥匙的礼物。

于 2013-08-16T15:26:21.523 回答
17

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

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

与其他解决方案相比,此方法具有优势。它允许允许深度嵌套的参数。

而其他解决方案如:

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

不。


资源:

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

于 2014-09-25T21:02:18.873 回答
12

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

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

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

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

于 2013-12-13T14:09:54.620 回答
10

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

params.require(:lever).permit(:name,:lever_benefit_attributes => {})
于 2020-03-26T00:45:32.570 回答
6

尝试

params.require(:lever).permit(:name, leave_benefit_attributes: LeaveBenefit.attribute_names.collect { |att| att.to_sym })
于 2013-11-02T21:12:56.430 回答
-5

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

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

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

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

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

于 2013-07-23T14:01:14.640 回答