29

Есть ли способ в strong parameters, чтобы разрешить все атрибуты модели 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) это для разрешающего все для вложенных атрибутов

+0

попробуйте прочитать этот ответ может быть, это полезно. > http://stackoverflow.com/questions/14483963/rails-4-0-strong-parameters-nested-attributes-with-a-key-that-points-to-a-hash –

+0

спасибо, но я видел это , Если вы заметили, что он делает то же самое с фильтрацией выборочных атрибутов ('assets_attributes:: filename'), которая передает имя файла. Я хочу разрешить все параметры для вложенных атрибутов – AnkitG

ответ

10

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

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

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

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

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

+1

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

+17

Если хэш, который вы получали, хранится в сериализованном столбце JSON, тогда для ключей нет проблем с безопасностью. (За исключением существующих проблем с слишком большим объемом ввода). У меня есть этот вариант использования, и я хотел бы разрешить любой произвольный ключ в хеше. –

+2

Существуют и другие способы обеспечения атрибутов. Например, объекты Command, которые вытесняют неперечисленные параметры, намного лучше подходят, IMHO. – karmajunkie

46

Единственная ситуация, я столкнулся, когда позволяет произвольные ключи в гнездовой 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 ключа.

+0

Огромное вам спасибо, вы экономите много времени :) –

+1

Это правильный ответ! вы заслуживаете зеленый флажок! –

+2

Почему 'params.require (: post) .fetch (: options, nil)' вместо 'params.require (: post) [: options]'? –

5

попробовать

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

Во-первых, убедитесь, что вы действительно хотите, чтобы все значения в вложенной хэш. Прочитайте Damien MATHIEU's answer, чтобы понять потенциальное открытие дыр в безопасности ...

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

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.'s answer, но немного более элегантной, так как вы не получите никаких Unpermitted parameters: lever_benefit_attributes предупреждений/ошибок.

15

На самом деле существует способ только белого списка всех вложенных параметров.

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

+2

Это не будет работать для глубоко вложенных параметров в Rails 5. Смотрите, почему здесь: http://eileencodes.com/posts/actioncontroller-parameters-now-returns-an-object-instead-of-a-hash/ – rmcsharry

 Смежные вопросы

  • Нет связанных вопросов^_^