Как проверить взаимную исключительность параметров в Grape API (Ruby)

При определении API с помощью Grape есть очень удобный способ проверки наличия и типа параметров, например:

params do
    requires :param1, type: String
    optional :param1, type: Integer
end

Однако я не вижу удобного способа указать, что два параметра являются взаимоисключающими. Например, это будет что-то вроде:

params do
    requires :creatureName, type: String
    requires 
        either :scaleType, type: String
        or :furType, type: String 
end

Меня интересуют предложения по наиболее удобному способу обойти это.


person Rene Wooller    schedule 13.03.2014    source источник


Ответы (4)


Вы также можете использовать exactly_one_of:

params do
  optional :scale_type
  optional :fur_type
  exactly_one_of :scale_type, :fur_type
end

at_least_one_of, all_or_none_of также доступны. Подробнее об этом здесь

person Jaro    schedule 03.03.2017

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

params do
  optional :beer
  optional :wine
  mutually_exclusive :beer, :wine
end

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

person NARKOZ    schedule 05.06.2014

Ищем то же самое. Ваш вопрос заставил меня открыть капот и посмотреть, можно ли это сделать. Вот запрос на вытягивание

person oliverbarnes    schedule 11.04.2014

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

params do
    requires :creature_name, type: String
    optional :scale_type, type: String
    optional :fur_type, type: String 
end

post '/creatures/:creature_name' do
  unless param[:scale_type] || param[:fur_type]
    raise Grape::Exceptions::Validation,  { param: "scale_type / fur_type",
        message: "one of scale_type or fur_type must be provided" }
  end
  if param[:scale_type] && param[:fur_type]
    raise Grape::Exceptions::Validation,  { param: "scale_type / fur_type",
        message: "only one of scale_type or fur_type can be provided" }
  end
  # ...
end
person Neil Slater    schedule 13.03.2014
comment
Спасибо, Нейл, я также рассчитываю на то, что буду выписывать собственные чеки. Я оставлю этот вопрос открытым, чтобы узнать, знает ли кто-нибудь какие-нибудь приемы, которые могут хранить все это в блоке параметров или иным образом более удобным способом, чем проверка и создание исключений вручную. - person Rene Wooller; 14.03.2014