Skip to content

Commit

Permalink
Fix serializing of time/date columns using yaml serializer
Browse files Browse the repository at this point in the history
  • Loading branch information
fatkodima committed May 30, 2024
1 parent 67a1ec2 commit 5a6ff78
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 1 deletion.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
date/time columns using yaml serializer. Previously, these were serialized as ruby
objects which use a lot of space. Now they are serialized into strings.

## 15.1.0 (2023-10-22)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true

require "paper_trail/type_serializers/date_time_serializer"
require "paper_trail/type_serializers/postgres_array_serializer"

module PaperTrail
Expand All @@ -20,13 +21,22 @@ def for(klass, attr)
active_record_serializer.subtype,
active_record_serializer.delimiter
)
elsif ar_date_time?(active_record_serializer)
TypeSerializers::DateTimeSerializer.new(active_record_serializer)
else
active_record_serializer
end
end

private

DATE_TIME_TYPES = %i[timestamp timestamptz datetime date time].freeze
private_constant :DATE_TIME_TYPES

def ar_date_time?(obj)
DATE_TIME_TYPES.include?(obj.type)
end

# @api private
def ar_pg_array?(obj)
if defined?(::ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Array)
Expand Down
21 changes: 21 additions & 0 deletions lib/paper_trail/type_serializers/date_time_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

module PaperTrail
module TypeSerializers
# Provides an alternative method of serialization
# and deserialization of date related columns.
class DateTimeSerializer
def initialize(original_type)
@original_type = original_type
end

def serialize(value)
value&.to_json
end

def deserialize(value)
@original_type.deserialize(value)
end
end
end
end
21 changes: 21 additions & 0 deletions spec/paper_trail/attribute_serializers/object_attribute_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,27 @@ 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)
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/)
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

0 comments on commit 5a6ff78

Please sign in to comment.