Сильные параметры разрешают все атрибуты вложенных атрибутов
Есть ли способ сильные параметры, чтобы разрешить все атрибуты модели 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)
для , разрешающего все для вложенных атрибутов
Ответы
Ответ 1
Весь смысл сильных параметров в его названии: сделать ваши входные параметры сильными.
Разрешить все параметры было бы очень плохой идеей, так как это позволило бы любому вставить значения, которые вы не обязательно хотите обновлять своими пользователями.
В приведенном ниже примере вы указываете два параметра, которые вам в настоящее время необходимо предоставить:
[:lever_id, :explanation]
.
Если вы разрешили все параметры, кто-то мог бы изменить любое другое значение.
created_at
или lever_id
, например.
Это определенно будет проблемой безопасности, и именно поэтому вы не должны этого делать.
Явное указание всех ваших атрибутов может показаться скучным, когда вы это сделаете.
Но это необходимо для обеспечения безопасности вашего приложения.
Изменить: для людей, которые уменьшают это. Возможно, это не тот ответ, который вы ищете, но это тот ответ, который вам нужен.
Белые списки всех вложенных атрибутов - это огромный недостаток безопасности, который сильные параметры пытаются защитить вас, и вы его удаляете.
Взгляните на то, что привело к созданию strong_params, и как не использовать его может быть плохо для вас: https://gist.github.com/peternixey/1978249
Ответ 2
Единственная ситуация, с которой я столкнулся, когда разрешать произвольные ключи в хеше вложенных параметров, кажется мне разумной, - это писать в сериализованный столбец. Мне удалось справиться с этим следующим образом:
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
.
Ответ 3
На самом деле есть способ просто перечислить все вложенные параметры.
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
Ответ 4
Во-первых, убедитесь, что вы действительно хотите разрешить все значения во вложенном хэше. Прочтите ответ 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
.
Ответ 5
попробовать
params.require(:lever).permit(:name, leave_benefit_attributes: LeaveBenefit.attribute_names.collect { |att| att.to_sym })