Как в общем виде обработать javascriptовский null в ruby глобально?
Есть большое приложение на рельсах. Есть много контроллеров, моделей, много яваскрипт кода. Вдруг откуда не возьмись взялась проблема. Хочу решить элегантно не прибегая к рефакторингу многих мест в приложении.
Есть яваскрипт код который передает через форму в рельсовое приложение содержимое некоторой переменной. Ее значение может в ряде случаев быть: null. Допустим я не предпринимаю мер и шлю на сервер пост запрос прямо с этим null.
Это значение натыкается на рельсовый валидатор:
validates :district,
numericality:
{only_integer: true, greater_than_or_equal_to: -1, allow_nil: true}
И вуаля - имеем ошибку. Ошибки бы не было если бы я в браузере заменил null на nil. Или же в контроллере проманипулировал входными параметрами и сделал эту замену. Либо как то заменил валидатор. В общем случае представляется что нужно пробежать по всему коду и наделать кучу изменений. Вы сталкивались с этой проблемой как решить одним махом, ну или с минимальными усилиями?
PS
Возможно смастерить собственный валидатор типа:
allow_null
чтобы тот пропускал значения nil и строковый "null"? Если это сделать просто, то как добиться того чтобы в базу записывался NULL, а не 'null', тем более если поле в базе не строковое.
По-хорошему, нужно проводить валидацию данных на стороне клиента и не позволять отправление неверных данных.
По-быстрому можно добавить дополнительную валидацию, вставив её перед validates :district
Ну данный способ очевиден. И это сразу приводит к вопросу: "А где еще в приложении у меня такое может быть?" И начинаешь неделю сидеть искать и добавлять такие валидаторы)) Не пойдет. Это по быстрому для одного параметра.
Вот еще наметка в нужном мне стиле, но не рабочая до конца: application_controller.rb
before_action :ransform_params
def transform_params
params.transform_values! { |x|
if x =='null'
nil
else
x
end
}
end
Преимущества: Работает всюду в приложении
Недостатки:
1. Не пропустит любую строку null. Например заругается, если пользователь захочет взять себе никнейм null
2. Не работает с вложенными параметрами типа params = {:var => "null", user => {:nickname => "null"}}. Изменения коснутся только var, но не nickname
А по поводу того, что данные должны защищаться в браузере это конечно хорошо, но это не отменяет проверку на сервере. А то пользователи своими кривыми рученками в ручном режиме напихают в базу всякого такого, что сервер и упасть может. Так что пися руби приложение всегда отталкиваюсь от мысли, что данные пришли плохие, независимо от того есть ли защита в яваскриптах или нет. Но это уже не по теме вопроса
Антон Мисягин, чудес не бывает. Вариант с контроллером потенциально опасен и я бы не рекомендовал им пользоваться.
Проблему с джаваскриптом надо решать, а не игнорировать. Надо повышать качество кода.