module ActiveRecord
module Type
class Value # :nodoc:
attr_reader :precision, :scale, :limit
# Valid options are +precision+, +scale+, and +limit+. They are only
# used when dumping schema.
def initialize(options = {})
options.assert_valid_keys(:precision, :scale, :limit)
@precision = options[:precision]
@scale = options[:scale]
@limit = options[:limit]
end
# The simplified type that this object represents. Returns a symbol such
# as +:string+ or +:integer+
def type; end
# Type casts a string from the database into the appropriate ruby type.
# Classes which do not need separate type casting behavior for database
# and user provided values should override +cast_value+ instead.
def type_cast_from_database(value)
type_cast(value)
end
# Type casts a value from user input (e.g. from a setter). This value may
# be a string from the form builder, or an already type cast value
# provided manually to a setter.
#
# Classes which do not need separate type casting behavior for database
# and user provided values should override +type_cast+ or +cast_value+
# instead.
def type_cast_from_user(value)
type_cast(value)
end
# Cast a value from the ruby type to a type that the database knows how
# to understand. The returned value from this method should be a
# +String+, +Numeric+, +Date+, +Time+, +Symbol+, +true+, +false+, or
# +nil+
def type_cast_for_database(value)
value
end
# Type cast a value for schema dumping. This method is private, as we are
# hoping to remove it entirely.
def type_cast_for_schema(value) # :nodoc:
value.inspect
end
# These predicates are not documented, as I need to look further into
# their use, and see if they can be removed entirely.
def number? # :nodoc:
false
end
def binary? # :nodoc:
false
end
def klass # :nodoc:
end
# Determines whether a value has changed for dirty checking. +old_value+
# and +new_value+ will always be type-cast. Types should not need to
# override this method.
def changed?(old_value, new_value, _new_value_before_type_cast)
old_value != new_value
end
# Determines whether the mutable value has been modified since it was
# read. Returns +false+ by default. This method should not be overridden
# directly. Types which return a mutable value should include
# +Type::Mutable+, which will define this method.
def changed_in_place?(*)
false
end
def ==(other)
self.class == other.class &&
precision == other.precision &&
scale == other.scale &&
limit == other.limit
end
private
def type_cast(value)
cast_value(value) unless value.nil?
end
# Convenience method for types which do not need separate type casting
# behavior for user and database inputs. Called by
# `type_cast_from_database` and `type_cast_from_user` for all values
# except `nil`.
def cast_value(value) # :doc:
value
end
end
end
end