1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
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
|