Строгие параметры разрешают все атрибуты для вложенных атрибутов
Есть ли способ в сильных параметрах разрешить все атрибуты модели 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
например.
Это определенно будет проблемой безопасности, и поэтому вам не следует этого делать.
Точное указание всех ваших атрибутов может показаться скучным, когда вы это делаете.
Но это необходимо для обеспечения безопасности вашего приложения.
Редактировать: Для людей, понижающих это. Возможно, это не тот ответ, который вы ищете, но это тот ответ, который вам нужен.
Белый список всех вложенных атрибутов - это огромный недостаток безопасности, с помощью которого сильные параметры пытаются защитить вас, и вы его удаляете.
Посмотрите, что приводит к созданию 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,:lever_benefit_attributes => {})
На самом деле есть способ просто внести в белый список все вложенные параметры.
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)
Не.
Источник:
Во-первых, убедитесь, что вы действительно хотите разрешить все значения во вложенном хэше. Прочитайте ответ Дэмиена МАТЬЕ, чтобы понять потенциальное открытие дыр в безопасности...
Если вам все еще нужно / нужно разрешить все значения в хэше (для этого есть совершенно допустимые варианты использования, например, хранение неструктурированных, предоставленных пользователем метаданных для записи), вы можете достичь этого, используя следующие биты кода:
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 })