Мы работаем над перестройкой наших пользовательских телефонов, чтобы разделить (на внешнем интерфейсе) выбор префикса международного кода телефона и номера без префикса.
Но на серверной стороне мы храним только "normalized_phone "с использованием Phony
gem
Предположим, что входящая полезная нагрузка может содержать несколько атрибутов
{ user: {
international_prefix: '+33',
number_without_prefix: '42424242',
last_name: 'xxx'
} }
и ее модель
class User
field :normalized_phone # includes both international_prefix and number_without_prefix
field :last_name
validate :last_name, ...
validate :normalized_phone_is_plausible
def number_without_prefix; ... end
def international_prefix; ... end
def normalized_phone_is_plausible?
errors.add(:normalized_phone, :invalid) unless Phony.plausible?(normalized_phone)
end
Мы хотим проинформировать интерфейспользователь
- Если международный код недействителен первым
- Если действительный номер недействителен, когда действителен международный телефон
Но при использовании этого наБэкенд / с другими приложениями, нас это не особо волнует, и мы не хотим видеть те же ошибки (только то, что normalized_phone
допустимо или нет).
Пока что мы 'Мы использовали ActiveModel, чтобы легко сериализовать ошибки (model.errors.map(&:errors_to_json)
). Проблема в том, что у нас другое представление ошибки на стороне интерфейса (потому что phone
сериализуется как 2 разных атрибута) и представление бэкэнда / БД (один "normalized_phone")
У нас естьслужба редакции, которая отвечает за обновление различных атрибутов пользователя, включая телефон, и обработку различных черновых состояний. По сути, наш основной логический вызов ведет себя так:
Наша логика в настоящее время такова
# controller
def update
transform_client_side_attributes_to_server_side_attributes
edition_service.new(model, params).call() # will call amongst others model.validate after assigning new attributes
render_json_using_activemodel_errors_for(model)
# =>
# { data: {...},
# errors: [...], # each ActiveModel error is serialized there
# }
end
def transform_client_side_attributes_to_server_side_attributes
international_prefix = params.xxx[:international_prefix]
number_without_prefix = params.xxx[:number_without_prefix]
if valid_prefix?(international_prefix)
if valid_number_for_prefix(number_without_prefix, international_prefix)
params[:normalized_phone] = normalize(number_without_prefix, international_prefix)
else
model.errors.add(:number_without_prefix, :invalid)
end
else
model.errors.add(:international_prefix, xxx)
return
end
end
Как вы можете видеть, поскольку у нас есть ошибки, специфичные для внешнего интерфейса, мы добавляем ошибки активной модели непосредственно в моделькак это очень удобно для сериализации. Проблема в том, что edition_service будет вызывать в какой-то момент model.validate
, и это приведет к удалению других ошибок проверки.
Есть ли способ предотвратить удаление ошибок при выполнении проверок? Чтобы мы могли составить несколько проверок, определенных для самой модели, и некоторые проверки для внешнего интерфейса?
Я понимаю, что ActiveModel может быть не предназначен для этого конкретного сценария, но создается впечатление, что он должен легко адаптироваться.
Должен ли я просто переопределить метод model.validate_without_clearing_errors
или, возможно, переключиться на другой подход?