From a4730dc96019738d31f0df85e2239a834ae0ee22 Mon Sep 17 00:00:00 2001 From: fatkodima Date: Sat, 27 Jan 2024 19:58:53 +0200 Subject: [PATCH] Fix serializing of time/date columns using yaml serializer --- CHANGELOG.md | 4 ++- .../cast_attribute_serializer.rb | 8 +++++- .../object_attribute_spec.rb | 26 +++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f177347b..86b3d5fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,9 @@ recommendations of [keepachangelog.com](http://keepachangelog.com/). ### Fixed -- None +- [#1458](https://github.com/paper-trail-gem/paper_trail/pull/1416) - Fix serializing + of time/date columns using yaml serializer. Previously, these were serialized as ruby + objects which uses a lot of space. Now they are serialized into strings. ## 15.1.0 (2023-10-22) diff --git a/lib/paper_trail/attribute_serializers/cast_attribute_serializer.rb b/lib/paper_trail/attribute_serializers/cast_attribute_serializer.rb index 1371b3b5..79a803b3 100644 --- a/lib/paper_trail/attribute_serializers/cast_attribute_serializer.rb +++ b/lib/paper_trail/attribute_serializers/cast_attribute_serializer.rb @@ -44,7 +44,13 @@ def deserialize(attr, val) end def serialize(attr, val) - AttributeSerializerFactory.for(@klass, attr).serialize(val) + serialized = AttributeSerializerFactory.for(@klass, attr).serialize(val) + case serialized + when Date, Time + @klass.connection.type_cast(serialized) + else + serialized + end end end end diff --git a/spec/paper_trail/attribute_serializers/object_attribute_spec.rb b/spec/paper_trail/attribute_serializers/object_attribute_spec.rb index 3bcc3e36..2581cc4f 100644 --- a/spec/paper_trail/attribute_serializers/object_attribute_spec.rb +++ b/spec/paper_trail/attribute_serializers/object_attribute_spec.rb @@ -40,6 +40,32 @@ module AttributeSerializers end end end + + describe "#serialize" do + it "serializes a time object into a plain string" do + time = Time.zone.local(2015, 7, 15, 20, 34, 0) + attrs = { "created_at" => time } + described_class.new(Widget).serialize(attrs) + + if ENV["DB"] == "postgres" || ENV["DB"] == "sqlite" + expect(attrs["created_at"]).not_to be_a(ActiveSupport::TimeWithZone) + expect(attrs["created_at"]).to be_a(String) + expect(attrs["created_at"]).to match(/2015/) + else + expect(attrs["created_at"].to_i).to eq(time.to_i) + end + end + end + + describe "#deserialize" do + it "deserializes a time object correctly" do + time = 1.day.ago + attrs = { "created_at" => time } + described_class.new(Widget).serialize(attrs) + described_class.new(Widget).deserialize(attrs) + expect(attrs["created_at"].to_i).to eq(time.to_i) + end + end end end end