Если вам когда-либо приходилось импортировать данные из CSV-файла в веб-приложение, то велика вероятность, что ваш опыт был не очень удачным. Вам нужно подготовить файл с необходимыми столбцами, экспортировать в .csv и убедиться, что разделитель указан правильно. (Как ни странно, несмотря на то, что CSV означает «значения, разделенные запятыми», разделителем может быть другой символ, например точка с запятой или табуляция). На этом веселье не заканчивается. Если в ваших данных есть какие-либо ошибки, например, неправильное форматирование или пропущенные значения, приложение подскажет вам, что нужно исправить, прежде чем продолжить. Теперь вам нужно вернуться в Excel или Google Sheets и найти ошибочные ячейки. Все повторяется снова и снова.
Создавая функцию массового импорта местоположений для Mapzy, нашей программы поиска магазинов с открытым исходным кодом и возможностью самостоятельного хостинга, мы хотели обеспечить лучший опыт импорта для наших пользователей. Мы хотели избавить их от необходимости возиться с экспортом файлов и выбором разделителей, а также упростить исправление ошибок импорта.
В результате инноваций, которые можно сравнить разве что с изобретением первого iPhone, мы пришли к следующему: На экране импорта мы предоставляем встроенную электронную таблицу, в которой уже заполнены правильные заголовки. Вместо того чтобы выбирать файл со своего компьютера, пользователи просто копируют и вставляют свои CSV-данные в эту таблицу и нажимают большую красную кнопку. Если есть какие-либо ошибки, мы просто выделяем соответствующие ячейки в электронной таблице. Таким образом, пользователи могут легко исправить их прямо на месте, без необходимости возиться с отдельным файлом и проходить весь процесс заново.
Дамы и господа, без лишних слов представляю вам — импортер местоположений Mapzy:
Если возникают ошибки, мы обрабатываем их следующим образом:
Для тех, кому интересна техническая сторона вопроса, далее следует более подробная информация.
Для электронной таблицы мы используем замечательную библиотеку Jspreadsheet. Если ошибок нет, импорт происходит в два этапа, потому что импорт большого количества местоположений требует большого количества обращений к Mapbox geocoding API (геокодирование — это преобразование адреса в долготу и широту), который ограничен по скорости.
На первом этапе мы проверяем только наличие информации и ее правильное форматирование. Например, если отсутствует название местоположения, мы выделяем эту ошибку в электронной таблице. Если все выглядит хорошо, мы сохраняем местоположения в базу данных с помощью замечательной библиотеки Activerecord-Import, но пропускаем вызов API геокодирования. Вместо этого мы помечаем эти местоположения как «подлежащие геокодированию».
На втором этапе мы запускаем фоновое задание (с помощью Sidekiq и Redis), которое просматривает базу данных и проверяет все места, относящиеся к данной карте, и при необходимости геокодирует их адреса. Если попытка геокодирования не увенчалась успехом, мы позже просим пользователя исправить адрес из его панели Mapzy.
Если вас заинтересовал код, посмотрите location_imports_controller.rb, location_import.rb и batch_geocode_worker.rb.
Дополнительным техническим бонусом этого подхода является то, что нам не нужно иметь дело с отображением столбцов из CSV-файла в наши модели данных, что само по себе может быть очень сложной задачей.