сильные параметры разрешают все атрибуты для вложенных атрибутов

есть ли способ в сильный параметров разрешить все атрибуты модель 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

для сильных параметров рычага я пишу в настоящее время это

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

есть ли способ для вложенные атрибуты я могу написать, чтобы разрешить все атрибуты без явного указания имени атрибутов, как lever_id и explanation ?

Примечание: Пожалуйста, не путайте этот вопрос с permit! или permit(:all) это разрешение всех вложенных атрибутов

5 ответов


весь смысл сильных параметров в его названии: сделайте ваши входные параметры сильными.
Разрешение всех параметров было бы очень плохой идеей, так как это позволило бы любому вставлять значения, которые вы не обязательно хотите обновлять своими пользователями.

В приведенном примере вы упоминаете два параметра, которые в настоящее время необходимо предоставить:
[:lever_id, :explanation].

Если вы разрешили все параметры, то было бы возможно для кого-то изменить любое другое значение.
created_at или lever_id например.

Это определенно будет проблемой безопасности, и именно поэтому вы не должны этого делать.
Явное указание всех ваших атрибутов может показаться скучным, когда вы это делаете.
Но это необходимо для обеспечения безопасности вашего приложения.

редактировать: для людей downvoting это. Возможно, это не тот ответ, который вы ищете, но он вам нужен.
Белый список всех вложенных атрибутов огромен недостаток безопасности, который сильный params пытается защитить вас, и вы его удаляете.
Взгляните на то, что приводит к созданию strong_params, и как не использовать его может быть плохо для вас:https://gist.github.com/peternixey/1978249


единственная ситуация, с которой я столкнулся, когда разрешение произвольных ключей во вложенном хэше params кажется мне разумным, - это при записи в сериализованный столбец. Мне удалось справиться с этим так:

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 ключ.


на самом деле есть способ просто белый-список всех вложенных параметров.

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


во-первых, убедитесь, что вы действительно хотите, чтобы все значения на вложенный хэш. Читать через ответ Дамьена Матье понять потенциальное отверстие отверстий безопасностью...

Если вам все еще нужно / хотите разрешить все значения в хэше (для этого есть вполне допустимые варианты использования, например, хранение неструктурированных пользовательских метаданных для записи), вы можете достичь этого, используя следующие биты кода:

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 предупреждения/ошибки.


попробовать

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