123456789_123456789_123456789_123456789_123456789_

Module: ActiveJob::Arguments

Relationships & Source Files
Defined in: activejob/lib/active_job/arguments.rb

Constant Summary

Instance Method Summary

Instance Method Details

#convert_to_global_id_hash(argument) (private)

[ GitHub ]

  
# File 'activejob/lib/active_job/arguments.rb', line 190

def convert_to_global_id_hash(argument)
  { GLOBALID_KEY => argument.to_global_id.to_s }
rescue URI::GID::MissingModelIdError
  raise SerializationError, "Unable to serialize #{argument.class} " \
    "without an id. (Maybe you forgot to call save?)"
end

#custom_serialized?(hash) ⇒ Boolean (private)

[ GitHub ]

  
# File 'activejob/lib/active_job/arguments.rb', line 137

def custom_serialized?(hash)
  hash.key?(OBJECT_SERIALIZER_KEY)
end

#deserialize(arguments)

Deserializes a set of arguments. Intrinsic types that can safely be deserialized without mutation are returned as-is. Arrays/Hashes are deserialized element by element. All other types are deserialized using GlobalID.

[ GitHub ]

  
# File 'activejob/lib/active_job/arguments.rb', line 42

def deserialize(arguments)
  arguments.map { |argument| deserialize_argument(argument) }
rescue
  raise DeserializationError
end

#deserialize_argument(argument) (private)

[ GitHub ]

  
# File 'activejob/lib/active_job/arguments.rb', line 110

def deserialize_argument(argument)
  case argument
  when nil, true, false, String, Integer, Float
    argument
  when Array
    argument.map { |arg| deserialize_argument(arg) }
  when Hash
    if serialized_global_id?(argument)
      deserialize_global_id argument
    elsif custom_serialized?(argument)
      Serializers.deserialize(argument)
    else
      deserialize_hash(argument)
    end
  else
    raise ArgumentError, "Can only deserialize primitive arguments: #{argument.inspect}"
  end
end

#deserialize_global_id(hash) (private)

[ GitHub ]

  
# File 'activejob/lib/active_job/arguments.rb', line 133

def deserialize_global_id(hash)
  GlobalID::Locator.locate hash[GLOBALID_KEY]
end

#deserialize_hash(serialized_hash) (private)

[ GitHub ]

  
# File 'activejob/lib/active_job/arguments.rb', line 147

def deserialize_hash(serialized_hash)
  result = serialized_hash.transform_values { |v| deserialize_argument(v) }
  if result.delete(WITH_INDIFFERENT_ACCESS_KEY)
    result = result.with_indifferent_access
  elsif symbol_keys = result.delete(SYMBOL_KEYS_KEY)
    result = transform_symbol_keys(result, symbol_keys)
  elsif symbol_keys = result.delete(RUBY2_KEYWORDS_KEY)
    result = transform_symbol_keys(result, symbol_keys)
    result = Hash.ruby2_keywords_hash(result)
  end
  result
end

#serialize(arguments)

Serializes a set of arguments. Intrinsic types that can safely be serialized without mutation are returned as-is. Arrays/Hashes are serialized element by element. All other types are serialized using GlobalID.

[ GitHub ]

  
# File 'activejob/lib/active_job/arguments.rb', line 34

def serialize(arguments)
  arguments.map { |argument| serialize_argument(argument) }
end

#serialize_argument(argument) (private)

[ GitHub ]

  
# File 'activejob/lib/active_job/arguments.rb', line 71

def serialize_argument(argument)
  case argument
  when nil, true, false, Integer, Float # Types that can hardly be subclassed
    argument
  when String
    if argument.class == String
      argument
    else
      begin
        Serializers.serialize(argument)
      rescue SerializationError
        argument
      end
    end
  when GlobalID::Identification
    convert_to_global_id_hash(argument)
  when Array
    argument.map { |arg| serialize_argument(arg) }
  when ActiveSupport::HashWithIndifferentAccess
    serialize_indifferent_hash(argument)
  when Hash
    symbol_keys = argument.each_key.grep(Symbol).map!(&:to_s)
    aj_hash_key = if Hash.ruby2_keywords_hash?(argument)
      RUBY2_KEYWORDS_KEY
    else
      SYMBOL_KEYS_KEY
    end
    result = serialize_hash(argument)
    result[aj_hash_key] = symbol_keys
    result
  else
    if argument.respond_to?(:permitted?) && argument.respond_to?(:to_h)
      serialize_indifferent_hash(argument.to_h)
    else
      Serializers.serialize(argument)
    end
  end
end

#serialize_hash(argument) (private)

[ GitHub ]

  
# File 'activejob/lib/active_job/arguments.rb', line 141

def serialize_hash(argument)
  argument.each_with_object({}) do |(key, value), hash|
    hash[serialize_hash_key(key)] = serialize_argument(value)
  end
end

#serialize_hash_key(key) (private)

[ GitHub ]

  
# File 'activejob/lib/active_job/arguments.rb', line 160

def serialize_hash_key(key)
  case key
  when *RESERVED_KEYS
    raise SerializationError.new("Can't serialize a Hash with reserved key #{key.inspect}")
  when String, Symbol
    key.to_s
  else
    raise SerializationError.new("Only string and symbol hash keys may be serialized as job arguments, but #{key.inspect} is a #{key.class}")
  end
end

#serialize_indifferent_hash(indifferent_hash) (private)

[ GitHub ]

  
# File 'activejob/lib/active_job/arguments.rb', line 171

def serialize_indifferent_hash(indifferent_hash)
  result = serialize_hash(indifferent_hash)
  result[WITH_INDIFFERENT_ACCESS_KEY] = serialize_argument(true)
  result
end

#serialized_global_id?(hash) ⇒ Boolean (private)

[ GitHub ]

  
# File 'activejob/lib/active_job/arguments.rb', line 129

def serialized_global_id?(hash)
  hash.size == 1 && hash.include?(GLOBALID_KEY)
end

#transform_symbol_keys(hash, symbol_keys) (private)

[ GitHub ]

  
# File 'activejob/lib/active_job/arguments.rb', line 177

def transform_symbol_keys(hash, symbol_keys)
  # NOTE: HashWithIndifferentAccess#transform_keys always
  # returns stringified keys with indifferent access
  # so we call #to_h here to ensure keys are symbolized.
  hash.to_h.transform_keys do |key|
    if symbol_keys.include?(key)
      key.to_sym
    else
      key
    end
  end
end