Class: DataMapper::Type

Inherits:
Object
  • Object
show all
Defined in:
lib/dm-core/type.rb

Overview

Types

Provides means of writing custom types for properties. Each type is based on a ruby primitive and handles its own serialization and materialization, and therefore is responsible for providing those methods.

To see complete list of supported types, see documentation for Property::PRIMITIVES. dm-types library provides less common types such as ip address, uuid, json, yaml, uri, slug, version, file path, bcrypt hash and so forth.

Defining new Types

To define a new type, subclass DataMapper::Type, pick ruby primitive, and set the options for this type.

class LowerCase < DataMapper::Type
  primitive        String
  auto_validation  true
  length           255
end

Following this, you will be able to use LowerCase as a type for any given property. If special materialization and serialization is required, override the class methods

class LowerCase < DataMapper::Type
  primitive        String
  auto_validation  true
  length           255

  def self.dump(value, property)
    return nil unless value
    value.to_s.downcase
  end

  def self.load(value)
    value
  end
end

Properties of LowerCase type now will downcase it’s values before it is persisted to the storage.

One more real world example from dm-types library is a JSON type that stores values serialized as JSON, and often useful for embedded values:

module DataMapper

module Types
  class Json < DataMapper::Type
    primitive String
    length    65535
    lazy      true

    def self.load(value, property)
      if value.nil?
        nil
      elsif value.kind_of?(String)
        ::JSON.load(value)
      else
        raise ArgumentError, '+value+ of a property of JSON type must be nil or a String'
      end
    end

    def self.dump(value, property)
      if value.nil? || value.kind_of?(String)
        value
      else
        ::JSON.dump(value)
      end
    end

    def self.typecast(value, property)
      if value.nil? || value.kind_of?(Array) || value.kind_of?(Hash)
        value
      else
        ::JSON.load(value.to_s)
      end
    end
  end # class Json
  JSON = Json
end # module Types

end # module DataMapper

Constant Summary collapse

PROPERTY_OPTIONS =

Until cooperation of Property and Type does not change, each must have a separate list of options, because plugins (ex.: dm-validations) may want to extend one or the other, and expects no side effects

[
  :accessor, :reader, :writer,
  :lazy, :default, :nullable, :key, :serial, :field, :size, :length,
  :format, :index, :unique_index, :auto_validation,
  :validates, :unique, :precision, :scale, :min, :max
]

Class Method Summary collapse

Class Method Details

.bind(property) ⇒ Object

A hook to allow types to extend or modify property it’s bound to. Implementations are not supposed to modify the state of the type class, and should produce no side-effects on the type class.



186
187
188
# File 'lib/dm-core/type.rb', line 186

def self.bind(property)
  # no op
end

.configure(primitive_type, options) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

TODO: document



102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/dm-core/type.rb', line 102

def configure(primitive_type, options)
  warn "DataMapper.Type.configure is deprecated, specify the primitive and options explicitly (#{caller[0]})"

  @_primitive_type = primitive_type
  @_options = options

  def self.inherited(base)
    base.primitive @_primitive_type
    @_options.each { |key, value| base.send(key, value) }
  end

  self
end

.dump(value, property) ⇒ Object

Stub instance method for dumping

Parameters:

  • value (Object, nil)

    value to dump

  • property (Property, nil)

    property the type is being used by

Returns:

  • (Object)

    Dumped object



167
168
169
# File 'lib/dm-core/type.rb', line 167

def self.dump(value, property)
  value
end

.inherited(base) ⇒ Object



108
109
110
111
# File 'lib/dm-core/type.rb', line 108

def self.inherited(base)
  base.primitive @_primitive_type
  @_options.each { |key, value| base.send(key, value) }
end

.load(value, property) ⇒ Object

Stub instance method for loading

Parameters:

  • value (Object, nil)

    value to serialize

  • property (Property, nil)

    property the type is being used by

Returns:

  • (Object)

    Serialized object. Must be the same type as the Ruby primitive



179
180
181
# File 'lib/dm-core/type.rb', line 179

def self.load(value, property)
  value
end

.optionsHash

Gives all the options set on this type

Returns:

  • (Hash)

    with all options and their values set on this type



149
150
151
152
153
154
155
156
# File 'lib/dm-core/type.rb', line 149

def options
  options = {}
  PROPERTY_OPTIONS.each do |method|
    next if (value = send(method)).nil?
    options[method] = value
  end
  options
end

.primitive(primitive = nil) ⇒ Class

Ruby primitive type to use as basis for this type. See Property::PRIMITIVES for list of types.

Parameters:

  • primitive (Class, nil) (defaults to: nil)

    The class for the primitive. If nil is passed in, it returns the current primitive

Returns:

  • (Class)

    if the <primitive> param is nil, return the current primitive.



126
127
128
129
# File 'lib/dm-core/type.rb', line 126

def primitive(primitive = nil)
  return @primitive if primitive.nil?
  @primitive = primitive
end