Skip to content

Commit 5a6ff78

Browse files
committed
Fix serializing of time/date columns using yaml serializer
1 parent 67a1ec2 commit 5a6ff78

File tree

4 files changed

+55
-1
lines changed

4 files changed

+55
-1
lines changed

CHANGELOG.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ recommendations of [keepachangelog.com](http://keepachangelog.com/).
1515

1616
### Fixed
1717

18-
- None
18+
- [#1458](https://github.com/paper-trail-gem/paper_trail/pull/1416) - Fix serializing
19+
date/time columns using yaml serializer. Previously, these were serialized as ruby
20+
objects which use a lot of space. Now they are serialized into strings.
1921

2022
## 15.1.0 (2023-10-22)
2123

lib/paper_trail/attribute_serializers/attribute_serializer_factory.rb

+10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# frozen_string_literal: true
22

3+
require "paper_trail/type_serializers/date_time_serializer"
34
require "paper_trail/type_serializers/postgres_array_serializer"
45

56
module PaperTrail
@@ -20,13 +21,22 @@ def for(klass, attr)
2021
active_record_serializer.subtype,
2122
active_record_serializer.delimiter
2223
)
24+
elsif ar_date_time?(active_record_serializer)
25+
TypeSerializers::DateTimeSerializer.new(active_record_serializer)
2326
else
2427
active_record_serializer
2528
end
2629
end
2730

2831
private
2932

33+
DATE_TIME_TYPES = %i[timestamp timestamptz datetime date time].freeze
34+
private_constant :DATE_TIME_TYPES
35+
36+
def ar_date_time?(obj)
37+
DATE_TIME_TYPES.include?(obj.type)
38+
end
39+
3040
# @api private
3141
def ar_pg_array?(obj)
3242
if defined?(::ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# frozen_string_literal: true
2+
3+
module PaperTrail
4+
module TypeSerializers
5+
# Provides an alternative method of serialization
6+
# and deserialization of date related columns.
7+
class DateTimeSerializer
8+
def initialize(original_type)
9+
@original_type = original_type
10+
end
11+
12+
def serialize(value)
13+
value&.to_json
14+
end
15+
16+
def deserialize(value)
17+
@original_type.deserialize(value)
18+
end
19+
end
20+
end
21+
end

spec/paper_trail/attribute_serializers/object_attribute_spec.rb

+21
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,27 @@ module AttributeSerializers
4040
end
4141
end
4242
end
43+
44+
describe "#serialize" do
45+
it "serializes a time object into a plain string" do
46+
time = Time.zone.local(2015, 7, 15, 20, 34, 0)
47+
attrs = { "created_at" => time }
48+
described_class.new(Widget).serialize(attrs)
49+
expect(attrs["created_at"]).not_to be_a(ActiveSupport::TimeWithZone)
50+
expect(attrs["created_at"]).to be_a(String)
51+
expect(attrs["created_at"]).to match(/2015/)
52+
end
53+
end
54+
55+
describe "#deserialize" do
56+
it "deserializes a time object correctly" do
57+
time = 1.day.ago
58+
attrs = { "created_at" => time }
59+
described_class.new(Widget).serialize(attrs)
60+
described_class.new(Widget).deserialize(attrs)
61+
expect(attrs["created_at"].to_i).to eq(time.to_i)
62+
end
63+
end
4364
end
4465
end
4566
end

0 commit comments

Comments
 (0)