Сериализация хэша с датами в виде рельсов YAML

TL; DR: Rails 5.1, Ruby 2.4.0 сериализует хэш, включающий объекты Time с кавычками вокруг строкового представления времени. Этих цитат не было в Rails 2.3, Ruby 1.8.7 и они ломали мое приложение; как мне от них избавиться?

Контекст и детали

Я обновляю приложение с Rails 2.3, Ruby 1.8.7 до Rails 5.1, Ruby 2.4.0. у меня есть ReportService класс, который имеет report_params аргумент конструктора, который принимает хеш. После создания этих объектов этот хэш сериализуется в формате YAML.

class ReportService < ApplicationRecord
  # irrelevant AR associations omitted
   serialize :report_params
   serialize :output_urls
end

Пользователь отправляет форму, содержащую детали отчета, который он хочет запустить, включая строку, которая анализируется с помощью Time.parse(), которая передается в качестве аргумента конструктора; таким образом, код (в процедурной форме для удаления ненужных деталей, с большим количеством посторонних вещей пропущен) выглядит так

offset = customer.timezone.nil? ? '+0000' : customer.timezone.formatted_offset(:time => start_date)
params[:date_from] = Time.parse("#{start_date} #{params[:hour_from]}:{params[:min_from]} #{offset}").utc.strftime('%Y-%m-%d %H:%M:%S')
report_args = {...
                report_params: { ...
                                 date: params[:date_from]
                               }
               }
ReportService.create(report_args)

Когда я смотрю в моей базе данных MYSQL, я обнаруживаю, что мое поле report_params выглядит ... date_from: '2017-12-27 00:00:00' ..., Соответствующий код в старой версии дает результат, который выглядит следующим образом ... date_from: 2017-12-27 00:00:00 ..., Это плохо, потому что YAML в этом поле анализируется (устаревшим) Java-приложением, которое опрашивает базу данных, чтобы проверить наличие новых записей, и кавычки, кажется, нарушают эту десериализацию (бросая java.lang.Exception: BaseProperties.getdate()); если я вручную отредактирую поле, чтобы удалить кавычки, приложение будет работать как положено. Как я могу предотвратить добавление этих кавычек?

1 ответ

Решение

Rails5.1/Ruby2.4 делают это правильно, так как 2017-12-27 00:00:00 не является допустимым значением yaml.

Хорошая вещь serialize принимает два параметра, второй является классом сериализатора.

Итак, все, что вам нужно сделать, это:

class ReportService < ApplicationRecord
  # irrelevant AR associations omitted
   serialize :report_params, MyYaml
   serialize :output_urls, MyYaml
end

и реализовать MyYaml, делегируя все, кроме date / time в YAML и производить все, что вам нужно для них.

Вышесказанное действительно для любого формата сериализованных данных, оно полностью не зависит от формата. Примеры.

Другие вопросы по тегам