2017-02-01 15 views
1

Контроллер получает объект JSONРельсы позволяют вложенной хэш атрибутов

{ 
    user: { 
    name: "string", 
    details: { 
     info1: "string", 
     info2: [] 
    } 
    } 
} 

Во время контроллера разрешения знает, что может разрешить некоторые определенные поля - в качестве имени - и хэш поля деталей со всеми вложенными атрибутами - также с массивами. Какое правильное решение для этой ситуации?

ПЛОХИЕ РЕШЕНИЯ

  1. permit не могут быть использованы, потому что я должен выбрать пользовательские допустимые поля

  2. tap do |whitelisted| не может быть использован, так как он не делает этого поля «разрешение»

  3. кейс ниже не может быть пользователем, потому что с массивами не работает

    details_keys = params[:user][:details].keys

    params.require(:user).permit(:name, details: details_keys)

+0

Я не уверен, что вы можете передать пустой массив. Вы пробовали сделать info2 пустой строкой и посмотреть, работает ли это? – gwalshington

+1

Определены ли атрибуты 'info1' и' infor2' вложенного объекта? или они динамичны? – SsouLlesS

+0

Они динамические – ukson

ответ

0

Добавление пустой массив может работать. Вы можете отключить проверку для вложенных атрибутов ?! Создаете ли вы динамические случайные поля ввода, которые вы не контролируете?

+0

У меня есть представление с большим количеством различных полей field_tags или checkbox, и я хочу отправлять только «измененные» поля в качестве поля JSON в моем объекте – ukson

0

Если вы хотите разрешить ключ, имеющий массив разрешенных скалярных значениям, то просто карта ключа к пустому массиву:

params.permit(key: []) 

допустимые скалярные типы String, Symbol, NilClass, Numeric, TrueClass, FalseClass, Date, Time, DateTime, StringIO, IO, ActionDispatch::Http::UploadedFile, and Rack::Test::UploadedFile

Итак, когда массив содержит некоторые нескалярных значения, как хэша, то у ou должны идти дальше, разрешая вложенные ключи тоже в массиве.

Скажет, у вас есть следующая структура:

{ 
    key: [ 
    { 
     attr1: 'string', 
     attr2: 10 
    }, 
    { 
     attr1: 'another string', 
     attr2: 100 
    } 
    ] 
} 

тогда разрешение идет таким образом:

params.permit(key: [:attr1, :attr2]) 

Теперь давайте предположим, что ваш случай выглядит следующим образом:

{ 
    user: { 
    name: "sting", 
    details: { 
     info1: "string", 
     info2: [1, true, :sym] // assume it contains only permitted scalar values 
    } 
    } 
} 

разрешение будет:

params.require(:user).permit(:name, details: [:info1, info2: []]) 

Чтобы автоматизировать этот процесс, позволяет предположить, details имеет 5 атрибуты с допустимыми значениями скалярных и более 3 атрибутов массива, которые также имеют только скалярные значения.

Первый срывать 5 ключей без массива details:

non_array_keys = params[:user][:details].reject { |_, v| v.class == Array }.keys 

Далее 3 клавиши массива внутри details:

array_keys = params[:user][:details].select { |_, v| v.class == Array }.keys.map { |k| { k => [] } } 

Теперь details_keys будет готов:

details_keys = non_array_keys << array_keys 
details_keys.flatten! 

Окончательное разрешение будет выглядеть так:

params.require(:user).permit(:name, details: details_keys) 

Если вложенные массивы будут содержать нескалярные значения, то, я думаю, у вас есть достаточно идеи по этому вопросу о том, как адаптироваться к вашим изменениям!

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: эта автоматизация не ценится, потому что вместо того, чтобы делать все это, достаточно простого вызова params.require(:user).permit!. Но это знаменует хэш-код и любой его субах как разрешенный и не проверяет разрешенные скаляры, что угодно. Крайне необходимо соблюдать осторожность при использовании permit!, так как это позволит назначать все текущие и будущие атрибуты модели.

Для получения дополнительной информации я настоятельно рекомендую подробно посмотреть на Rails official guide covering Strong Parameters.

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

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