1

Я использую Rails 5 для создания JSON Api.Rails 5. Сильные параметры не требуются, если установлен один ключ разрешения

Мой контроллер использует сильные параметры с одним требуют атрибута, как это:

params.require(:require_attribute).permit(:permit_attribute1,:permit_attribute2) 

Обычно я должен послать мой JSON как это:

{ 
    "require_attribute":{ 
     "permit_attribute1": "data", 
     "permit_attribute2": "data" 
    } 
} 

И если требуемый атрибут отсутствует, Я должен получить это сообщение:

"ActionController::ParameterMissing: param is missing or the value is empty: require_attribute" 

Моя проблема заключается в том, что если я удаляю требуемый атрибут из JSON, и у меня есть один атрибут permit, который имеет сильные параметры, он работает.

JSON Я посылаю:

{ 
    "permit_attribute1": "data", 
} 

Когда я Params в log у меня есть:

{ "permit1" => данные, "контроллер" => "mycontroller", "действие" => "создать", "require_attribute" => { "permit1" => 1}}

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

У кого-нибудь есть идея?

+0

Что вы используете для отправки этого «более простого» json? Является ли он угловатым/неустойчивым, случайно? –

+0

Я использую curl в консоли или Postman addon – Kramougna

ответ

3

Сильный параметр API был разработан с наиболее распространенными вариантами использования . Это не значит, что это серебряная пуля, чтобы справиться со всеми вашими проблемами .

http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters

require(key)

Обеспечивает параметр присутствует. Если он присутствует, возвращает параметр с заданным ключом, в противном случае возникает ошибка ActionController::ParameterMissing.

http://api.rubyonrails.org/classes/ActionController/Parameters.html#method-i-require

Как видно из приведенной выше настройки необходимых параметров на «плоской» хэш не действительно то, что сильные параметры API построен для. Скорее, он построен вокруг соглашений о рельсах, где параметры вложены под одним ключом.

Вы можете использовать'.require ', чтобы вытащить один ключ одновременно, но это было бы довольно неуклюжим.

Скорее вы можете имитировать то, что он делает, поднимая исключение, если ключ не присутствует:

def something_params 
    req = [:required_attribute1, :required_attribute2] 
    req.each do |k| 
    raise ActionController::ParameterMissing.new(k) unless params[k].present? 
    end 
    whitelisted = params.permit(:permit_attribute1, :permit_attribute2) 
end 

Однако лучший способ в целом может быть использование валидаций уровня модели - ActionController::ParameterMissing предполагается указать, что общее форматирование запроса отключено - не требуется отсутствие требуемого атрибута. Например, для форматированного запроса JSONAPI.org вы могли бы сделать:

params.require(:data).require(:attributes).permit(:email, :username) 

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

+1

Хорошо, но почему 'require' не поднимает ошибку, когда требуемого ключа нет? Похоже, это ожидаемое поведение здесь. – Caillou

+0

Нет, не совсем. Учтите, что параметры записываются в журнал до того, как рельсы совпадают даже с запросом маршрута и создают экземпляр контроллера. Я не уверен, является ли ошибка в том, как вы отправляете запрос или какую-то действительно странную проблему, когда Rack или некоторое промежуточное программное обеспечение принудительно вводят параметры запроса. – max

+0

Также '.require' фактически не изменяет' request.params'. Он возвращает копию. Если вы проверите журнал сервера, и параметры выглядят так, у вас есть что-то подозрительное. – max

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

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