mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Remove non-default serializers
This commit is contained in:
parent
e360ac1231
commit
3785a57299
10 changed files with 72 additions and 163 deletions
|
@ -57,10 +57,6 @@ That's it!
|
||||||
ActiveJob supports the following types of arguments by default:
|
ActiveJob supports the following types of arguments by default:
|
||||||
|
|
||||||
- Standard types (`NilClass`, `String`, `Integer`, `Fixnum`, `Bignum`, `Float`, `BigDecimal`, `TrueClass`, `FalseClass`)
|
- Standard types (`NilClass`, `String`, `Integer`, `Fixnum`, `Bignum`, `Float`, `BigDecimal`, `TrueClass`, `FalseClass`)
|
||||||
- `Symbol` (`:foo`, `:bar`, ...)
|
|
||||||
- `ActiveSupport::Duration` (`1.day`, `2.weeks`, ...)
|
|
||||||
- Classes constants (`ActiveRecord::Base`, `MySpecialService`, ...)
|
|
||||||
- Struct instances (`Struct.new('Rectangle', :width, :height).new(12, 20)`, ...)
|
|
||||||
- `Hash`. Keys should be of `String` or `Symbol` type
|
- `Hash`. Keys should be of `String` or `Symbol` type
|
||||||
- `ActiveSupport::HashWithIndifferentAccess`
|
- `ActiveSupport::HashWithIndifferentAccess`
|
||||||
- `Array`
|
- `Array`
|
||||||
|
|
|
@ -27,15 +27,11 @@ module ActiveJob
|
||||||
|
|
||||||
autoload :ArraySerializer
|
autoload :ArraySerializer
|
||||||
autoload :BaseSerializer
|
autoload :BaseSerializer
|
||||||
autoload :ClassSerializer
|
|
||||||
autoload :DurationSerializer
|
|
||||||
autoload :GlobalIDSerializer
|
autoload :GlobalIDSerializer
|
||||||
autoload :HashWithIndifferentAccessSerializer
|
autoload :HashWithIndifferentAccessSerializer
|
||||||
autoload :HashSerializer
|
autoload :HashSerializer
|
||||||
autoload :ObjectSerializer
|
autoload :ObjectSerializer
|
||||||
autoload :StandardTypeSerializer
|
autoload :StandardTypeSerializer
|
||||||
autoload :StructSerializer
|
|
||||||
autoload :SymbolSerializer
|
|
||||||
|
|
||||||
included do
|
included do
|
||||||
class_attribute :_additional_serializers, instance_accessor: false, instance_predicate: false
|
class_attribute :_additional_serializers, instance_accessor: false, instance_predicate: false
|
||||||
|
@ -46,14 +42,14 @@ module ActiveJob
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
# Returns list of known serializers
|
# Returns list of known serializers
|
||||||
def serializers
|
def serializers
|
||||||
self._additional_serializers + SERIALIZERS
|
self._additional_serializers + ActiveJob::Serializers::SERIALIZERS
|
||||||
end
|
end
|
||||||
|
|
||||||
# Adds a new serializer to a list of known serializers
|
# Adds a new serializer to a list of known serializers
|
||||||
def add_serializers(*serializers)
|
def add_serializers(*new_serializers)
|
||||||
check_duplicate_serializer_keys!(serializers)
|
check_duplicate_serializer_keys!(new_serializers)
|
||||||
|
|
||||||
@_additional_serializers = serializers + @_additional_serializers
|
self._additional_serializers = new_serializers + self._additional_serializers
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns a list of reserved keys, which cannot be used as keys for a hash
|
# Returns a list of reserved keys, which cannot be used as keys for a hash
|
||||||
|
@ -66,7 +62,7 @@ module ActiveJob
|
||||||
def check_duplicate_serializer_keys!(serializers)
|
def check_duplicate_serializer_keys!(serializers)
|
||||||
keys_to_add = serializers.select { |s| s.respond_to?(:key) }.map(&:key)
|
keys_to_add = serializers.select { |s| s.respond_to?(:key) }.map(&:key)
|
||||||
|
|
||||||
duplicate_keys = reserved_keys & keys_to_add
|
duplicate_keys = reserved_serializers_keys & keys_to_add
|
||||||
|
|
||||||
raise ArgumentError.new("Can't add serializers because of keys duplication: #{duplicate_keys}") if duplicate_keys.any?
|
raise ArgumentError.new("Can't add serializers because of keys duplication: #{duplicate_keys}") if duplicate_keys.any?
|
||||||
end
|
end
|
||||||
|
@ -75,21 +71,16 @@ module ActiveJob
|
||||||
# :nodoc:
|
# :nodoc:
|
||||||
SERIALIZERS = [
|
SERIALIZERS = [
|
||||||
::ActiveJob::Serializers::GlobalIDSerializer,
|
::ActiveJob::Serializers::GlobalIDSerializer,
|
||||||
::ActiveJob::Serializers::DurationSerializer,
|
|
||||||
::ActiveJob::Serializers::StructSerializer,
|
|
||||||
::ActiveJob::Serializers::SymbolSerializer,
|
|
||||||
::ActiveJob::Serializers::ClassSerializer,
|
|
||||||
::ActiveJob::Serializers::StandardTypeSerializer,
|
::ActiveJob::Serializers::StandardTypeSerializer,
|
||||||
::ActiveJob::Serializers::HashWithIndifferentAccessSerializer,
|
::ActiveJob::Serializers::HashWithIndifferentAccessSerializer,
|
||||||
::ActiveJob::Serializers::HashSerializer,
|
::ActiveJob::Serializers::HashSerializer,
|
||||||
::ActiveJob::Serializers::ArraySerializer
|
::ActiveJob::Serializers::ArraySerializer
|
||||||
].freeze
|
].freeze
|
||||||
private_constant :SERIALIZERS
|
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
# Returns serialized representative of the passed object.
|
# Returns serialized representative of the passed object.
|
||||||
# Will look up through all known serializers.
|
# Will look up through all known serializers.
|
||||||
# Raises `SerializationError` if it can't find a proper serializer.
|
# Raises `ActiveJob::SerializationError` if it can't find a proper serializer.
|
||||||
def serialize(argument)
|
def serialize(argument)
|
||||||
serializer = ::ActiveJob::Base.serializers.detect { |s| s.serialize?(argument) }
|
serializer = ::ActiveJob::Base.serializers.detect { |s| s.serialize?(argument) }
|
||||||
raise SerializationError.new("Unsupported argument type: #{argument.class.name}") unless serializer
|
raise SerializationError.new("Unsupported argument type: #{argument.class.name}") unless serializer
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module ActiveJob
|
|
||||||
module Serializers
|
|
||||||
# Provides methods to serialize and deserialize `Class` (`ActiveRecord::Base`, `MySpecialService`, ...)
|
|
||||||
class ClassSerializer < ObjectSerializer
|
|
||||||
class << self
|
|
||||||
def serialize(argument_klass)
|
|
||||||
{ key => "::#{argument_klass.name}" }
|
|
||||||
end
|
|
||||||
|
|
||||||
def key
|
|
||||||
"_aj_class"
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def klass
|
|
||||||
::Class
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,42 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module ActiveJob
|
|
||||||
module Serializers
|
|
||||||
# Provides methods to serialize and deserialize `ActiveSupport::Duration` (`1.day`, `2.weeks`, ...)
|
|
||||||
class DurationSerializer < ObjectSerializer
|
|
||||||
class << self
|
|
||||||
def serialize(duration)
|
|
||||||
{
|
|
||||||
key => duration.value,
|
|
||||||
parts_key => ::ActiveJob::Serializers.serialize(duration.parts)
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def deserialize(hash)
|
|
||||||
value = hash[key]
|
|
||||||
parts = ::ActiveJob::Serializers.deserialize(hash[parts_key])
|
|
||||||
|
|
||||||
klass.new(value, parts)
|
|
||||||
end
|
|
||||||
|
|
||||||
def key
|
|
||||||
"_aj_activesupport_duration"
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def klass
|
|
||||||
::ActiveSupport::Duration
|
|
||||||
end
|
|
||||||
|
|
||||||
def keys
|
|
||||||
super.push parts_key
|
|
||||||
end
|
|
||||||
|
|
||||||
def parts_key
|
|
||||||
"parts"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,38 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module ActiveJob
|
|
||||||
module Serializers
|
|
||||||
# Provides methods to serialize and deserialize struct instances
|
|
||||||
# (`Struct.new('Rectangle', :width, :height).new(12, 20)`)
|
|
||||||
class StructSerializer < ObjectSerializer
|
|
||||||
class << self
|
|
||||||
def serialize(object)
|
|
||||||
super.merge values_key => ::ActiveJob::Serializers.serialize(object.values)
|
|
||||||
end
|
|
||||||
|
|
||||||
def deserialize(hash)
|
|
||||||
values = ::ActiveJob::Serializers.deserialize(hash[values_key])
|
|
||||||
super.new(*values)
|
|
||||||
end
|
|
||||||
|
|
||||||
def key
|
|
||||||
"_aj_struct"
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def klass
|
|
||||||
::Struct
|
|
||||||
end
|
|
||||||
|
|
||||||
def keys
|
|
||||||
super.push values_key
|
|
||||||
end
|
|
||||||
|
|
||||||
def values_key
|
|
||||||
"values"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,28 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module ActiveJob
|
|
||||||
module Serializers
|
|
||||||
# Provides methods to serialize and deserialize `Symbol` (`:foo`, `:bar`, ...)
|
|
||||||
class SymbolSerializer < ObjectSerializer
|
|
||||||
class << self
|
|
||||||
def serialize(symbol)
|
|
||||||
{ key => symbol.to_s }
|
|
||||||
end
|
|
||||||
|
|
||||||
def deserialize(hash)
|
|
||||||
hash[key].to_sym
|
|
||||||
end
|
|
||||||
|
|
||||||
def key
|
|
||||||
"_aj_symbol"
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def klass
|
|
||||||
::Symbol
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -30,7 +30,7 @@ module Rails # :nodoc:
|
||||||
private
|
private
|
||||||
def application_job_file_name
|
def application_job_file_name
|
||||||
@application_job_file_name ||= if mountable_engine?
|
@application_job_file_name ||= if mountable_engine?
|
||||||
"app/jobs/#{namespaced_path}/application_job.rb"
|
"app/jobs/#{namespaced_path}/application_job.rb"
|
||||||
else
|
else
|
||||||
"app/jobs/application_job.rb"
|
"app/jobs/application_job.rb"
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,6 @@ require "helper"
|
||||||
require "active_job/arguments"
|
require "active_job/arguments"
|
||||||
require "models/person"
|
require "models/person"
|
||||||
require "active_support/core_ext/hash/indifferent_access"
|
require "active_support/core_ext/hash/indifferent_access"
|
||||||
require "active_support/duration"
|
|
||||||
require "jobs/kwargs_job"
|
require "jobs/kwargs_job"
|
||||||
|
|
||||||
class ArgumentSerializationTest < ActiveSupport::TestCase
|
class ArgumentSerializationTest < ActiveSupport::TestCase
|
||||||
|
@ -14,7 +13,6 @@ class ArgumentSerializationTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
[ nil, 1, 1.0, 1_000_000_000_000_000_000_000,
|
[ nil, 1, 1.0, 1_000_000_000_000_000_000_000,
|
||||||
"a", true, false, BigDecimal.new(5),
|
"a", true, false, BigDecimal.new(5),
|
||||||
:a, self, 1.day,
|
|
||||||
[ 1, "a" ],
|
[ 1, "a" ],
|
||||||
{ "a" => 1 }
|
{ "a" => 1 }
|
||||||
].each do |arg|
|
].each do |arg|
|
||||||
|
@ -23,7 +21,7 @@ class ArgumentSerializationTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
[ Object.new, Person.find("5").to_gid ].each do |arg|
|
[ :a, Object.new, self, Person.find("5").to_gid ].each do |arg|
|
||||||
test "does not serialize #{arg.class}" do
|
test "does not serialize #{arg.class}" do
|
||||||
assert_raises ActiveJob::SerializationError do
|
assert_raises ActiveJob::SerializationError do
|
||||||
ActiveJob::Arguments.serialize [ arg ]
|
ActiveJob::Arguments.serialize [ arg ]
|
||||||
|
@ -35,10 +33,6 @@ class ArgumentSerializationTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "serializes Struct" do
|
|
||||||
assert_arguments_unchanged Struct.new("Rectangle", :width, :height).new(10, 15)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "should convert records to Global IDs" do
|
test "should convert records to Global IDs" do
|
||||||
assert_arguments_roundtrip [@person]
|
assert_arguments_roundtrip [@person]
|
||||||
end
|
end
|
||||||
|
|
64
activejob/test/cases/serializers_test.rb
Normal file
64
activejob/test/cases/serializers_test.rb
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "helper"
|
||||||
|
require "active_job/serializers"
|
||||||
|
|
||||||
|
class SerializersTest < ActiveSupport::TestCase
|
||||||
|
class DummyValueObject
|
||||||
|
attr_accessor :value
|
||||||
|
|
||||||
|
def initialize(value)
|
||||||
|
@value = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class DummySerializer < ActiveJob::Serializers::ObjectSerializer
|
||||||
|
class << self
|
||||||
|
def serialize(object)
|
||||||
|
{ key => object.value }
|
||||||
|
end
|
||||||
|
|
||||||
|
def deserialize(hash)
|
||||||
|
DummyValueObject.new(hash[key])
|
||||||
|
end
|
||||||
|
|
||||||
|
def key
|
||||||
|
"_dummy_serializer"
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def klass
|
||||||
|
DummyValueObject
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
setup do
|
||||||
|
@value_object = DummyValueObject.new 123
|
||||||
|
ActiveJob::Base._additional_serializers = []
|
||||||
|
end
|
||||||
|
|
||||||
|
test "can't serialize unknown object" do
|
||||||
|
assert_raises ActiveJob::SerializationError do
|
||||||
|
ActiveJob::Serializers.serialize @value_object
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "won't deserialize unknown hash" do
|
||||||
|
hash = { "_dummy_serializer" => 123, "_aj_symbol_keys" => [] }
|
||||||
|
assert ActiveJob::Serializers.deserialize(hash), hash.except("_aj_symbol_keys")
|
||||||
|
end
|
||||||
|
|
||||||
|
test "adds new serializer" do
|
||||||
|
ActiveJob::Base.add_serializers DummySerializer
|
||||||
|
assert ActiveJob::Base.serializers.include?(DummySerializer)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "can't add serializer with the same key twice" do
|
||||||
|
ActiveJob::Base.add_serializers DummySerializer
|
||||||
|
assert_raises ArgumentError do
|
||||||
|
ActiveJob::Base.add_serializers DummySerializer
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -345,10 +345,6 @@ Supported types for arguments
|
||||||
ActiveJob supports the following types of arguments by default:
|
ActiveJob supports the following types of arguments by default:
|
||||||
|
|
||||||
- Basic types (`NilClass`, `String`, `Integer`, `Fixnum`, `Bignum`, `Float`, `BigDecimal`, `TrueClass`, `FalseClass`)
|
- Basic types (`NilClass`, `String`, `Integer`, `Fixnum`, `Bignum`, `Float`, `BigDecimal`, `TrueClass`, `FalseClass`)
|
||||||
- `Symbol` (`:foo`, `:bar`, ...)
|
|
||||||
- `ActiveSupport::Duration` (`1.day`, `2.weeks`, ...)
|
|
||||||
- Classes constants (`ActiveRecord::Base`, `MySpecialService`, ...)
|
|
||||||
- Struct instances (`Struct.new('Rectangle', :width, :height).new(12, 20)`, ...)
|
|
||||||
- `Hash`. Keys should be of `String` or `Symbol` type
|
- `Hash`. Keys should be of `String` or `Symbol` type
|
||||||
- `ActiveSupport::HashWithIndifferentAccess`
|
- `ActiveSupport::HashWithIndifferentAccess`
|
||||||
- `Array`
|
- `Array`
|
||||||
|
|
Loading…
Reference in a new issue