From ec686a471e0a54194fc9ec72e639785606597704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Fri, 9 Feb 2018 14:24:55 -0500 Subject: [PATCH] Simplify the implementation of custom serialziers Right now it is only possible to define serializers globally so we don't need to use a class attribute in the job class. --- activejob/lib/active_job/serializers.rb | 62 ++++++++----------- .../active_job/serializers/hash_serializer.rb | 2 +- activejob/test/cases/serializers_test.rb | 14 +++-- 3 files changed, 37 insertions(+), 41 deletions(-) diff --git a/activejob/lib/active_job/serializers.rb b/activejob/lib/active_job/serializers.rb index 68ed94896e..41113c521c 100644 --- a/activejob/lib/active_job/serializers.rb +++ b/activejob/lib/active_job/serializers.rb @@ -33,16 +33,31 @@ module ActiveJob autoload :ObjectSerializer autoload :StandardTypeSerializer - included do - class_attribute :_additional_serializers, instance_accessor: false, instance_predicate: false - self._additional_serializers = [] - end + mattr_accessor :_additional_serializers + self._additional_serializers = [] + + 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. + def serialize(argument) + serializer = serializers.detect { |s| s.serialize?(argument) } + raise SerializationError.new("Unsupported argument type: #{argument.class.name}") unless serializer + serializer.serialize(argument) + end + + # Returns deserialized object. + # Will look up through all known serializers. + # If no serializers found will raise `ArgumentError` + def deserialize(argument) + serializer = serializers.detect { |s| s.deserialize?(argument) } + raise ArgumentError, "Can only deserialize primitive arguments: #{argument.inspect}" unless serializer + serializer.deserialize(argument) + end - # Includes the method to list known serializers and to add new ones - module ClassMethods # Returns list of known serializers def serializers - self._additional_serializers + ActiveJob::Serializers::SERIALIZERS + self._additional_serializers end # Adds a new serializer to a list of known serializers @@ -68,33 +83,10 @@ module ActiveJob end end - # :nodoc: - SERIALIZERS = [ - ::ActiveJob::Serializers::GlobalIDSerializer, - ::ActiveJob::Serializers::StandardTypeSerializer, - ::ActiveJob::Serializers::HashWithIndifferentAccessSerializer, - ::ActiveJob::Serializers::HashSerializer, - ::ActiveJob::Serializers::ArraySerializer - ].freeze - - 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. - def serialize(argument) - serializer = ::ActiveJob::Base.serializers.detect { |s| s.serialize?(argument) } - raise SerializationError.new("Unsupported argument type: #{argument.class.name}") unless serializer - serializer.serialize(argument) - end - - # Returns deserialized object. - # Will look up through all known serializers. - # If no serializers found will raise `ArgumentError` - def deserialize(argument) - serializer = ::ActiveJob::Base.serializers.detect { |s| s.deserialize?(argument) } - raise ArgumentError, "Can only deserialize primitive arguments: #{argument.inspect}" unless serializer - serializer.deserialize(argument) - end - end + add_serializers GlobalIDSerializer, + StandardTypeSerializer, + HashWithIndifferentAccessSerializer, + HashSerializer, + ArraySerializer end end diff --git a/activejob/lib/active_job/serializers/hash_serializer.rb b/activejob/lib/active_job/serializers/hash_serializer.rb index eee081de7c..c4dcfaf094 100644 --- a/activejob/lib/active_job/serializers/hash_serializer.rb +++ b/activejob/lib/active_job/serializers/hash_serializer.rb @@ -38,7 +38,7 @@ module ActiveJob def serialize_hash_key(key) raise SerializationError.new("Only string and symbol hash keys may be serialized as job arguments, but #{key.inspect} is a #{key.class}") unless [String, Symbol].include?(key.class) - raise SerializationError.new("Can't serialize a Hash with reserved key #{key.inspect}") if ActiveJob::Base.reserved_serializers_keys.include?(key.to_s) + raise SerializationError.new("Can't serialize a Hash with reserved key #{key.inspect}") if ActiveJob::Serializers.reserved_serializers_keys.include?(key.to_s) key.to_s end diff --git a/activejob/test/cases/serializers_test.rb b/activejob/test/cases/serializers_test.rb index 90d4155b3b..3b526c932b 100644 --- a/activejob/test/cases/serializers_test.rb +++ b/activejob/test/cases/serializers_test.rb @@ -36,7 +36,11 @@ class SerializersTest < ActiveSupport::TestCase setup do @value_object = DummyValueObject.new 123 - ActiveJob::Base._additional_serializers = [] + @original_serializers = ActiveJob::Serializers.serializers + end + + teardown do + ActiveJob::Serializers._additional_serializers = @original_serializers end test "can't serialize unknown object" do @@ -51,14 +55,14 @@ class SerializersTest < ActiveSupport::TestCase end test "adds new serializer" do - ActiveJob::Base.add_serializers DummySerializer - assert ActiveJob::Base.serializers.include?(DummySerializer) + ActiveJob::Serializers.add_serializers DummySerializer + assert ActiveJob::Serializers.serializers.include?(DummySerializer) end test "can't add serializer with the same key twice" do - ActiveJob::Base.add_serializers DummySerializer + ActiveJob::Serializers.add_serializers DummySerializer assert_raises ArgumentError do - ActiveJob::Base.add_serializers DummySerializer + ActiveJob::Serializers.add_serializers DummySerializer end end end