aboutsummaryrefslogtreecommitdiffstats
path: root/activejob
diff options
context:
space:
mode:
authorRafael França <rafaelmfranca@gmail.com>2018-02-20 13:35:34 -0500
committerGitHub <noreply@github.com>2018-02-20 13:35:34 -0500
commitb7b73de0df1fb2619508c99c5c10a3cab628d48e (patch)
tree2938ea3bfe7ab6a2ec789a2b3277a7ed891c06a9 /activejob
parentc42dafd437f6392bf0fb41ac751a8e231940b67e (diff)
parent67391879f606e4ad9ef64210a23431e071b3df8c (diff)
downloadrails-b7b73de0df1fb2619508c99c5c10a3cab628d48e.tar.gz
rails-b7b73de0df1fb2619508c99c5c10a3cab628d48e.tar.bz2
rails-b7b73de0df1fb2619508c99c5c10a3cab628d48e.zip
Merge pull request #32026 from bogdanvlviv/improve-30941
Improve ActiveJob custom argument serializers #30941
Diffstat (limited to 'activejob')
-rw-r--r--activejob/lib/active_job/serializers.rb18
-rw-r--r--activejob/lib/active_job/serializers/object_serializer.rb32
-rw-r--r--activejob/lib/active_job/serializers/time_with_zone_serializer.rb21
-rw-r--r--activejob/test/cases/argument_serialization_test.rb8
-rw-r--r--activejob/test/cases/serializers_test.rb2
5 files changed, 56 insertions, 25 deletions
diff --git a/activejob/lib/active_job/serializers.rb b/activejob/lib/active_job/serializers.rb
index 9930ae0823..df66e66659 100644
--- a/activejob/lib/active_job/serializers.rb
+++ b/activejob/lib/active_job/serializers.rb
@@ -4,17 +4,18 @@ require "set"
module ActiveJob
# The <tt>ActiveJob::Serializers</tt> module is used to store a list of known serializers
- # and to add new ones. It also has helpers to serialize/deserialize objects
- module Serializers
+ # and to add new ones. It also has helpers to serialize/deserialize objects.
+ module Serializers # :nodoc:
extend ActiveSupport::Autoload
extend ActiveSupport::Concern
autoload :ObjectSerializer
autoload :SymbolSerializer
autoload :DurationSerializer
+ autoload :DateTimeSerializer
autoload :DateSerializer
+ autoload :TimeWithZoneSerializer
autoload :TimeSerializer
- autoload :DateTimeSerializer
mattr_accessor :_additional_serializers
self._additional_serializers = Set.new
@@ -22,7 +23,7 @@ module ActiveJob
class << self
# Returns serialized representative of the passed object.
# Will look up through all known serializers.
- # Raises `ActiveJob::SerializationError` if it can't find a proper serializer.
+ # Raises <tt>ActiveJob::SerializationError</tt> if it can't find a proper serializer.
def serialize(argument)
serializer = serializers.detect { |s| s.serialize?(argument) }
raise SerializationError.new("Unsupported argument type: #{argument.class.name}") unless serializer
@@ -31,23 +32,23 @@ module ActiveJob
# Returns deserialized object.
# Will look up through all known serializers.
- # If no serializers found will raise `ArgumentError`
+ # If no serializer found will raise <tt>ArgumentError</tt>.
def deserialize(argument)
serializer_name = argument[Arguments::OBJECT_SERIALIZER_KEY]
raise ArgumentError, "Serializer name is not present in the argument: #{argument.inspect}" unless serializer_name
serializer = serializer_name.safe_constantize
- raise ArgumentError, "Serializer #{serializer_name} is not know" unless serializer
+ raise ArgumentError, "Serializer #{serializer_name} is not known" unless serializer
serializer.deserialize(argument)
end
- # Returns list of known serializers
+ # Returns list of known serializers.
def serializers
self._additional_serializers
end
- # Adds a new serializer to a list of known serializers
+ # Adds new serializers to a list of known serializers.
def add_serializers(*new_serializers)
self._additional_serializers += new_serializers.flatten
end
@@ -57,6 +58,7 @@ module ActiveJob
DurationSerializer,
DateTimeSerializer,
DateSerializer,
+ TimeWithZoneSerializer,
TimeSerializer
end
end
diff --git a/activejob/lib/active_job/serializers/object_serializer.rb b/activejob/lib/active_job/serializers/object_serializer.rb
index 9f59e8236f..1dfd1e44be 100644
--- a/activejob/lib/active_job/serializers/object_serializer.rb
+++ b/activejob/lib/active_job/serializers/object_serializer.rb
@@ -2,25 +2,25 @@
module ActiveJob
module Serializers
- # Base class for serializing and deserializing custom times.
+ # Base class for serializing and deserializing custom objects.
#
- # Example
+ # Example:
#
- # class MoneySerializer < ActiveJob::Serializers::ObjectSerializer
- # def serialize(money)
- # super("cents" => money.cents, "currency" => money.currency)
- # end
+ # class MoneySerializer < ActiveJob::Serializers::ObjectSerializer
+ # def serialize(money)
+ # super("amount" => money.amount, "currency" => money.currency)
+ # end
#
- # def deserialize(hash)
- # Money.new(hash["cents"], hash["currency"])
- # end
+ # def deserialize(hash)
+ # Money.new(hash["amount"], hash["currency"])
+ # end
#
- # private
+ # private
#
- # def klass
- # Money
- # end
- # end
+ # def klass
+ # Money
+ # end
+ # end
class ObjectSerializer
include Singleton
@@ -43,10 +43,10 @@ module ActiveJob
raise NotImplementedError
end
- protected
+ private
# The class of the object that will be serialized.
- def klass
+ def klass # :doc:
raise NotImplementedError
end
end
diff --git a/activejob/lib/active_job/serializers/time_with_zone_serializer.rb b/activejob/lib/active_job/serializers/time_with_zone_serializer.rb
new file mode 100644
index 0000000000..43017fc75b
--- /dev/null
+++ b/activejob/lib/active_job/serializers/time_with_zone_serializer.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module ActiveJob
+ module Serializers
+ class TimeWithZoneSerializer < ObjectSerializer # :nodoc:
+ def serialize(time)
+ super("value" => time.iso8601)
+ end
+
+ def deserialize(hash)
+ Time.iso8601(hash["value"]).in_time_zone
+ end
+
+ private
+
+ def klass
+ ActiveSupport::TimeWithZone
+ end
+ end
+ end
+end
diff --git a/activejob/test/cases/argument_serialization_test.rb b/activejob/test/cases/argument_serialization_test.rb
index 5d27813832..e5f1f087fe 100644
--- a/activejob/test/cases/argument_serialization_test.rb
+++ b/activejob/test/cases/argument_serialization_test.rb
@@ -102,6 +102,14 @@ class ArgumentSerializationTest < ActiveSupport::TestCase
assert_instance_of ActiveSupport::HashWithIndifferentAccess, perform_round_trip([indifferent_access]).first
end
+ test "should maintain time with zone" do
+ Time.use_zone "Alaska" do
+ time_with_zone = Time.new(2002, 10, 31, 2, 2, 2).in_time_zone
+ assert_instance_of ActiveSupport::TimeWithZone, perform_round_trip([time_with_zone]).first
+ assert_arguments_unchanged time_with_zone
+ end
+ end
+
test "should disallow non-string/symbol hash keys" do
assert_raises ActiveJob::SerializationError do
ActiveJob::Arguments.serialize [ { 1 => 2 } ]
diff --git a/activejob/test/cases/serializers_test.rb b/activejob/test/cases/serializers_test.rb
index a86f168d03..bee0c061bd 100644
--- a/activejob/test/cases/serializers_test.rb
+++ b/activejob/test/cases/serializers_test.rb
@@ -73,7 +73,7 @@ class SerializersTest < ActiveSupport::TestCase
ActiveJob::Serializers.deserialize(hash)
end
assert_equal(
- "Serializer DoNotExist is not know",
+ "Serializer DoNotExist is not known",
error.message
)
end