mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Improve documentation on custom serializers
This commit is contained in:
parent
a5f7357a3d
commit
71721dc1c9
4 changed files with 47 additions and 79 deletions
|
@ -52,17 +52,8 @@ MyJob.set(wait: 1.week).perform_later(record) # Enqueue a job to be performed 1
|
|||
|
||||
That's it!
|
||||
|
||||
## Supported types for arguments
|
||||
|
||||
ActiveJob supports the following types of arguments by default:
|
||||
|
||||
- Standard types (`NilClass`, `String`, `Integer`, `Fixnum`, `Bignum`, `Float`, `BigDecimal`, `TrueClass`, `FalseClass`)
|
||||
- `Hash`. Keys should be of `String` or `Symbol` type
|
||||
- `ActiveSupport::HashWithIndifferentAccess`
|
||||
- `Array`
|
||||
|
||||
|
||||
### GlobalID support
|
||||
## GlobalID support
|
||||
|
||||
Active Job supports [GlobalID serialization](https://github.com/rails/globalid/) for parameters. This makes it possible
|
||||
to pass live Active Record objects to your job instead of class/id pairs, which
|
||||
|
@ -90,53 +81,6 @@ end
|
|||
This works with any class that mixes in GlobalID::Identification, which
|
||||
by default has been mixed into Active Record classes.
|
||||
|
||||
### Serializers
|
||||
|
||||
You can extend list of supported types for arguments. You just need to define your own serializer.
|
||||
|
||||
```ruby
|
||||
class MySpecialSerializer
|
||||
class << self
|
||||
# Check if this object should be serialized using this serializer
|
||||
def serialize?(argument)
|
||||
object.is_a? MySpecialValueObject
|
||||
end
|
||||
|
||||
# Convert an object to a simpler representative using supported object types.
|
||||
# The recommended representative is a Hash with a specific key. Keys can be of basic types only
|
||||
def serialize(object)
|
||||
{
|
||||
key => ActiveJob::Serializers.serialize(object.value)
|
||||
'another_attribute' => ActiveJob::Serializers.serialize(object.another_attribute)
|
||||
}
|
||||
end
|
||||
|
||||
# Check if this serialized value be deserialized using this serializer
|
||||
def deserialize?(argument)
|
||||
object.is_a?(Hash) && object.keys == [key, 'another_attribute']
|
||||
end
|
||||
|
||||
# Convert serialized value into a proper object
|
||||
def deserialize(object)
|
||||
value = ActiveJob::Serializers.deserialize(object[key])
|
||||
another_attribute = ActiveJob::Serializers.deserialize(object['another_attribute'])
|
||||
MySpecialValueObject.new value, another_attribute
|
||||
end
|
||||
|
||||
# Define this method if you are using a hash as a representative.
|
||||
# This key will be added to a list of restricted keys for hashes. Use basic types only
|
||||
def key
|
||||
"_aj_custom_dummy_value_object"
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
And now you just need to add this serializer to a list:
|
||||
|
||||
```ruby
|
||||
ActiveJob::Base.add_serializers(MySpecialSerializer)
|
||||
```
|
||||
|
||||
## Supported queueing systems
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
module ActiveJob
|
||||
module Serializers
|
||||
# Implement the basic interface for Active Job arguments serializers.
|
||||
class BaseSerializer
|
||||
include Singleton
|
||||
|
||||
|
@ -9,24 +10,29 @@ module ActiveJob
|
|||
delegate :serialize?, :deserialize?, :serialize, :deserialize, to: :instance
|
||||
end
|
||||
|
||||
# Determines if an argument should be serialized by a serializer.
|
||||
def serialize?(argument)
|
||||
argument.is_a?(klass)
|
||||
end
|
||||
|
||||
# Determines if an argument should be deserialized by a serializer.
|
||||
def deserialize?(_argument)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
# Serializes an argument to a JSON primitive type.
|
||||
def serialize(_argument)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
# Deserilizes an argument form a JSON primiteve type.
|
||||
def deserialize(_argument)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# The class of the object that will be serialized.
|
||||
def klass
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
|
|
@ -2,6 +2,25 @@
|
|||
|
||||
module ActiveJob
|
||||
module Serializers
|
||||
# Base class for serializing and deserializing custom times.
|
||||
#
|
||||
# Example
|
||||
#
|
||||
# class MoneySerializer < ActiveJob::Serializers::ObjectSerializer
|
||||
# def serialize(money)
|
||||
# super("cents" => money.cents, "currency" => money.currency)
|
||||
# end
|
||||
#
|
||||
# def deserialize(hash)
|
||||
# Money.new(hash["cents"], hash["currency"])
|
||||
# end
|
||||
#
|
||||
# private
|
||||
#
|
||||
# def klass
|
||||
# Money
|
||||
# end
|
||||
# end
|
||||
class ObjectSerializer < BaseSerializer
|
||||
def serialize(hash)
|
||||
{ OBJECT_SERIALIZER_KEY => self.class.name }.merge!(hash)
|
||||
|
|
|
@ -345,6 +345,12 @@ Supported types for arguments
|
|||
ActiveJob supports the following types of arguments by default:
|
||||
|
||||
- Basic types (`NilClass`, `String`, `Integer`, `Fixnum`, `Bignum`, `Float`, `BigDecimal`, `TrueClass`, `FalseClass`)
|
||||
- `Symbol
|
||||
- `ActiveSupport::Duration`
|
||||
- `Date`
|
||||
- `Time`
|
||||
- `DateTime`
|
||||
- `ActiveSupport::TimeWithZone`
|
||||
- `Hash`. Keys should be of `String` or `Symbol` type
|
||||
- `ActiveSupport::HashWithIndifferentAccess`
|
||||
- `Array`
|
||||
|
@ -382,38 +388,31 @@ by default has been mixed into Active Record classes.
|
|||
You can extend list of supported types for arguments. You just need to define your own serializer.
|
||||
|
||||
```ruby
|
||||
class MySpecialSerializer
|
||||
class << self
|
||||
# Check if this object should be serialized using this serializer
|
||||
class MoneySerializer < ActiveJob::Serializers::ObjectSerializer
|
||||
# Check if this object should be serialized using this serializer.
|
||||
def serialize?(argument)
|
||||
argument.is_a? MySpecialValueObject
|
||||
argument.is_a? Money
|
||||
end
|
||||
|
||||
# Convert an object to a simpler representative using supported object types.
|
||||
# The recommended representative is a Hash with a specific key. Keys can be of basic types only
|
||||
# The recommended representative is a Hash with a specific key. Keys can be of basic types only.
|
||||
# You should call `super` to add the custom serializer type to the hash
|
||||
def serialize(object)
|
||||
{
|
||||
key => ActiveJob::Serializers.serialize(object.value)
|
||||
'another_attribute' => ActiveJob::Serializers.serialize(object.another_attribute)
|
||||
}
|
||||
super(
|
||||
"cents" => object.cents,
|
||||
"currency" => object.currency
|
||||
)
|
||||
end
|
||||
|
||||
# Check if this serialized value be deserialized using this serializer
|
||||
# Check if this serialized value be deserialized using this serializer.
|
||||
# ActiveJob::Serializers::ObjectSerializer#deserialize? already take care of this.
|
||||
def deserialize?(argument)
|
||||
argument.is_a?(Hash) && argument.keys == [key, 'another_attribute']
|
||||
super
|
||||
end
|
||||
|
||||
# Convert serialized value into a proper object
|
||||
def deserialize(object)
|
||||
value = ActiveJob::Serializers.deserialize(object[key])
|
||||
another_attribute = ActiveJob::Serializers.deserialize(object['another_attribute'])
|
||||
MySpecialValueObject.new value, another_attribute
|
||||
end
|
||||
|
||||
# Define this method if you are using a hash as a representative.
|
||||
# This key will be added to a list of restricted keys for hashes. Use basic types only
|
||||
def key
|
||||
"_aj_custom_dummy_value_object"
|
||||
def deserialize(hash)
|
||||
Money.new hash["cents"], hash["currency"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -422,7 +421,7 @@ end
|
|||
And now you just need to add this serializer to a list:
|
||||
|
||||
```ruby
|
||||
ActiveJob::Base.add_serializers(MySpecialSerializer)
|
||||
Rails.application.config.active_job.custom_serializers << MySpecialSerializer
|
||||
```
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue