activerecord 4.2.11.3 → 5.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (229) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1029 -1349
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +6 -7
  5. data/examples/performance.rb +2 -2
  6. data/lib/active_record.rb +7 -3
  7. data/lib/active_record/aggregations.rb +35 -25
  8. data/lib/active_record/association_relation.rb +2 -2
  9. data/lib/active_record/associations.rb +305 -204
  10. data/lib/active_record/associations/alias_tracker.rb +19 -16
  11. data/lib/active_record/associations/association.rb +10 -8
  12. data/lib/active_record/associations/association_scope.rb +73 -102
  13. data/lib/active_record/associations/belongs_to_association.rb +20 -32
  14. data/lib/active_record/associations/builder/association.rb +28 -34
  15. data/lib/active_record/associations/builder/belongs_to.rb +41 -18
  16. data/lib/active_record/associations/builder/collection_association.rb +8 -24
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +11 -11
  18. data/lib/active_record/associations/builder/has_many.rb +4 -4
  19. data/lib/active_record/associations/builder/has_one.rb +10 -5
  20. data/lib/active_record/associations/builder/singular_association.rb +2 -9
  21. data/lib/active_record/associations/collection_association.rb +40 -43
  22. data/lib/active_record/associations/collection_proxy.rb +55 -29
  23. data/lib/active_record/associations/foreign_association.rb +1 -1
  24. data/lib/active_record/associations/has_many_association.rb +20 -71
  25. data/lib/active_record/associations/has_many_through_association.rb +8 -52
  26. data/lib/active_record/associations/has_one_association.rb +12 -5
  27. data/lib/active_record/associations/join_dependency.rb +28 -18
  28. data/lib/active_record/associations/join_dependency/join_association.rb +13 -12
  29. data/lib/active_record/associations/preloader.rb +13 -4
  30. data/lib/active_record/associations/preloader/association.rb +45 -51
  31. data/lib/active_record/associations/preloader/collection_association.rb +0 -6
  32. data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
  33. data/lib/active_record/associations/preloader/has_one.rb +0 -8
  34. data/lib/active_record/associations/preloader/through_association.rb +5 -4
  35. data/lib/active_record/associations/singular_association.rb +6 -0
  36. data/lib/active_record/associations/through_association.rb +11 -3
  37. data/lib/active_record/attribute.rb +61 -17
  38. data/lib/active_record/attribute/user_provided_default.rb +23 -0
  39. data/lib/active_record/attribute_assignment.rb +27 -140
  40. data/lib/active_record/attribute_decorators.rb +6 -5
  41. data/lib/active_record/attribute_methods.rb +79 -26
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +1 -1
  43. data/lib/active_record/attribute_methods/dirty.rb +46 -86
  44. data/lib/active_record/attribute_methods/primary_key.rb +2 -2
  45. data/lib/active_record/attribute_methods/query.rb +2 -2
  46. data/lib/active_record/attribute_methods/read.rb +26 -42
  47. data/lib/active_record/attribute_methods/serialization.rb +13 -16
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +42 -9
  49. data/lib/active_record/attribute_methods/write.rb +13 -24
  50. data/lib/active_record/attribute_mutation_tracker.rb +70 -0
  51. data/lib/active_record/attribute_set.rb +30 -3
  52. data/lib/active_record/attribute_set/builder.rb +6 -4
  53. data/lib/active_record/attributes.rb +194 -81
  54. data/lib/active_record/autosave_association.rb +33 -15
  55. data/lib/active_record/base.rb +30 -18
  56. data/lib/active_record/callbacks.rb +36 -40
  57. data/lib/active_record/coders/yaml_column.rb +20 -8
  58. data/lib/active_record/collection_cache_key.rb +31 -0
  59. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +431 -122
  60. data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -3
  61. data/lib/active_record/connection_adapters/abstract/database_statements.rb +40 -22
  62. data/lib/active_record/connection_adapters/abstract/quoting.rb +62 -8
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +46 -38
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +229 -185
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +52 -13
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +275 -115
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +32 -33
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +83 -32
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +384 -221
  70. data/lib/active_record/connection_adapters/column.rb +27 -41
  71. data/lib/active_record/connection_adapters/connection_specification.rb +2 -21
  72. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +22 -0
  73. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +57 -0
  74. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +69 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +59 -0
  76. data/lib/active_record/connection_adapters/mysql2_adapter.rb +22 -101
  77. data/lib/active_record/connection_adapters/postgresql/column.rb +6 -10
  78. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +3 -3
  79. data/lib/active_record/connection_adapters/postgresql/oid.rb +1 -6
  80. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +23 -57
  81. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +1 -1
  83. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
  84. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +7 -22
  85. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +3 -3
  86. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +1 -26
  87. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +2 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +0 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +4 -4
  90. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +50 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +23 -16
  92. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +0 -4
  93. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +2 -2
  94. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +1 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +1 -1
  96. data/lib/active_record/connection_adapters/postgresql/quoting.rb +18 -11
  97. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +29 -10
  98. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -79
  99. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +54 -0
  100. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +174 -128
  101. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
  102. data/lib/active_record/connection_adapters/postgresql_adapter.rb +184 -112
  103. data/lib/active_record/connection_adapters/schema_cache.rb +36 -23
  104. data/lib/active_record/connection_adapters/sql_type_metadata.rb +32 -0
  105. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +15 -0
  106. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +134 -110
  107. data/lib/active_record/connection_adapters/statement_pool.rb +28 -11
  108. data/lib/active_record/connection_handling.rb +5 -5
  109. data/lib/active_record/core.rb +72 -104
  110. data/lib/active_record/counter_cache.rb +9 -20
  111. data/lib/active_record/dynamic_matchers.rb +1 -20
  112. data/lib/active_record/enum.rb +110 -76
  113. data/lib/active_record/errors.rb +72 -47
  114. data/lib/active_record/explain_registry.rb +1 -1
  115. data/lib/active_record/explain_subscriber.rb +1 -1
  116. data/lib/active_record/fixture_set/file.rb +19 -4
  117. data/lib/active_record/fixtures.rb +76 -40
  118. data/lib/active_record/gem_version.rb +4 -4
  119. data/lib/active_record/inheritance.rb +27 -40
  120. data/lib/active_record/integration.rb +4 -4
  121. data/lib/active_record/legacy_yaml_adapter.rb +18 -2
  122. data/lib/active_record/locale/en.yml +3 -2
  123. data/lib/active_record/locking/optimistic.rb +10 -14
  124. data/lib/active_record/locking/pessimistic.rb +1 -1
  125. data/lib/active_record/log_subscriber.rb +40 -22
  126. data/lib/active_record/migration.rb +304 -133
  127. data/lib/active_record/migration/command_recorder.rb +59 -18
  128. data/lib/active_record/migration/compatibility.rb +90 -0
  129. data/lib/active_record/model_schema.rb +92 -40
  130. data/lib/active_record/nested_attributes.rb +45 -34
  131. data/lib/active_record/null_relation.rb +15 -7
  132. data/lib/active_record/persistence.rb +112 -72
  133. data/lib/active_record/querying.rb +6 -5
  134. data/lib/active_record/railtie.rb +20 -13
  135. data/lib/active_record/railties/controller_runtime.rb +1 -1
  136. data/lib/active_record/railties/databases.rake +47 -38
  137. data/lib/active_record/readonly_attributes.rb +1 -1
  138. data/lib/active_record/reflection.rb +182 -57
  139. data/lib/active_record/relation.rb +152 -100
  140. data/lib/active_record/relation/batches.rb +133 -33
  141. data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
  142. data/lib/active_record/relation/calculations.rb +80 -101
  143. data/lib/active_record/relation/delegation.rb +6 -19
  144. data/lib/active_record/relation/finder_methods.rb +58 -46
  145. data/lib/active_record/relation/from_clause.rb +32 -0
  146. data/lib/active_record/relation/merger.rb +13 -42
  147. data/lib/active_record/relation/predicate_builder.rb +99 -105
  148. data/lib/active_record/relation/predicate_builder/array_handler.rb +11 -16
  149. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +78 -0
  150. data/lib/active_record/relation/predicate_builder/base_handler.rb +17 -0
  151. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +17 -0
  152. data/lib/active_record/relation/predicate_builder/class_handler.rb +27 -0
  153. data/lib/active_record/relation/predicate_builder/range_handler.rb +17 -0
  154. data/lib/active_record/relation/query_attribute.rb +19 -0
  155. data/lib/active_record/relation/query_methods.rb +274 -238
  156. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  157. data/lib/active_record/relation/spawn_methods.rb +3 -6
  158. data/lib/active_record/relation/where_clause.rb +173 -0
  159. data/lib/active_record/relation/where_clause_factory.rb +37 -0
  160. data/lib/active_record/result.rb +4 -3
  161. data/lib/active_record/runtime_registry.rb +1 -1
  162. data/lib/active_record/sanitization.rb +94 -65
  163. data/lib/active_record/schema.rb +23 -22
  164. data/lib/active_record/schema_dumper.rb +33 -22
  165. data/lib/active_record/schema_migration.rb +10 -4
  166. data/lib/active_record/scoping.rb +17 -6
  167. data/lib/active_record/scoping/default.rb +19 -6
  168. data/lib/active_record/scoping/named.rb +39 -28
  169. data/lib/active_record/secure_token.rb +38 -0
  170. data/lib/active_record/serialization.rb +2 -4
  171. data/lib/active_record/statement_cache.rb +15 -13
  172. data/lib/active_record/store.rb +8 -3
  173. data/lib/active_record/suppressor.rb +54 -0
  174. data/lib/active_record/table_metadata.rb +64 -0
  175. data/lib/active_record/tasks/database_tasks.rb +30 -40
  176. data/lib/active_record/tasks/mysql_database_tasks.rb +7 -15
  177. data/lib/active_record/tasks/postgresql_database_tasks.rb +11 -2
  178. data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
  179. data/lib/active_record/timestamp.rb +16 -9
  180. data/lib/active_record/touch_later.rb +58 -0
  181. data/lib/active_record/transactions.rb +138 -56
  182. data/lib/active_record/type.rb +66 -17
  183. data/lib/active_record/type/adapter_specific_registry.rb +130 -0
  184. data/lib/active_record/type/date.rb +2 -45
  185. data/lib/active_record/type/date_time.rb +2 -49
  186. data/lib/active_record/type/internal/abstract_json.rb +33 -0
  187. data/lib/active_record/type/internal/timezone.rb +15 -0
  188. data/lib/active_record/type/serialized.rb +9 -14
  189. data/lib/active_record/type/time.rb +3 -21
  190. data/lib/active_record/type/type_map.rb +4 -4
  191. data/lib/active_record/type_caster.rb +7 -0
  192. data/lib/active_record/type_caster/connection.rb +29 -0
  193. data/lib/active_record/type_caster/map.rb +19 -0
  194. data/lib/active_record/validations.rb +33 -32
  195. data/lib/active_record/validations/absence.rb +24 -0
  196. data/lib/active_record/validations/associated.rb +10 -3
  197. data/lib/active_record/validations/length.rb +36 -0
  198. data/lib/active_record/validations/presence.rb +12 -12
  199. data/lib/active_record/validations/uniqueness.rb +24 -21
  200. data/lib/rails/generators/active_record/migration.rb +7 -0
  201. data/lib/rails/generators/active_record/migration/migration_generator.rb +7 -4
  202. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +8 -3
  203. data/lib/rails/generators/active_record/migration/templates/migration.rb +4 -1
  204. data/lib/rails/generators/active_record/model/model_generator.rb +21 -15
  205. data/lib/rails/generators/active_record/model/templates/model.rb +3 -0
  206. metadata +50 -35
  207. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
  208. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  209. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +0 -11
  210. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  211. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
  212. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  213. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  214. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  215. data/lib/active_record/type/big_integer.rb +0 -13
  216. data/lib/active_record/type/binary.rb +0 -50
  217. data/lib/active_record/type/boolean.rb +0 -31
  218. data/lib/active_record/type/decimal.rb +0 -64
  219. data/lib/active_record/type/decimal_without_scale.rb +0 -11
  220. data/lib/active_record/type/decorator.rb +0 -14
  221. data/lib/active_record/type/float.rb +0 -19
  222. data/lib/active_record/type/integer.rb +0 -59
  223. data/lib/active_record/type/mutable.rb +0 -16
  224. data/lib/active_record/type/numeric.rb +0 -36
  225. data/lib/active_record/type/string.rb +0 -40
  226. data/lib/active_record/type/text.rb +0 -11
  227. data/lib/active_record/type/time_value.rb +0 -38
  228. data/lib/active_record/type/unsigned_integer.rb +0 -15
  229. data/lib/active_record/type/value.rb +0 -110
@@ -1,23 +1,72 @@
1
- require 'active_record/type/decorator'
2
- require 'active_record/type/mutable'
3
- require 'active_record/type/numeric'
4
- require 'active_record/type/time_value'
5
- require 'active_record/type/value'
6
-
7
- require 'active_record/type/big_integer'
8
- require 'active_record/type/binary'
9
- require 'active_record/type/boolean'
1
+ require 'active_model/type'
2
+
3
+ require 'active_record/type/internal/abstract_json'
4
+ require 'active_record/type/internal/timezone'
5
+
10
6
  require 'active_record/type/date'
11
7
  require 'active_record/type/date_time'
12
- require 'active_record/type/decimal'
13
- require 'active_record/type/decimal_without_scale'
14
- require 'active_record/type/float'
15
- require 'active_record/type/integer'
16
- require 'active_record/type/serialized'
17
- require 'active_record/type/string'
18
- require 'active_record/type/text'
19
8
  require 'active_record/type/time'
20
- require 'active_record/type/unsigned_integer'
9
+
10
+ require 'active_record/type/serialized'
11
+ require 'active_record/type/adapter_specific_registry'
21
12
 
22
13
  require 'active_record/type/type_map'
23
14
  require 'active_record/type/hash_lookup_type_map'
15
+
16
+ module ActiveRecord
17
+ module Type
18
+ @registry = AdapterSpecificRegistry.new
19
+
20
+ class << self
21
+ attr_accessor :registry # :nodoc:
22
+ delegate :add_modifier, to: :registry
23
+
24
+ # Add a new type to the registry, allowing it to be referenced as a
25
+ # symbol by {ActiveRecord::Base.attribute}[rdoc-ref:Attributes::ClassMethods#attribute].
26
+ # If your type is only meant to be used with a specific database adapter, you can
27
+ # do so by passing <tt>adapter: :postgresql</tt>. If your type has the same
28
+ # name as a native type for the current adapter, an exception will be
29
+ # raised unless you specify an +:override+ option. <tt>override: true</tt> will
30
+ # cause your type to be used instead of the native type. <tt>override:
31
+ # false</tt> will cause the native type to be used over yours if one exists.
32
+ def register(type_name, klass = nil, **options, &block)
33
+ registry.register(type_name, klass, **options, &block)
34
+ end
35
+
36
+ def lookup(*args, adapter: current_adapter_name, **kwargs) # :nodoc:
37
+ registry.lookup(*args, adapter: adapter, **kwargs)
38
+ end
39
+
40
+ private
41
+
42
+ def current_adapter_name
43
+ ActiveRecord::Base.connection.adapter_name.downcase.to_sym
44
+ end
45
+ end
46
+
47
+ Helpers = ActiveModel::Type::Helpers
48
+ BigInteger = ActiveModel::Type::BigInteger
49
+ Binary = ActiveModel::Type::Binary
50
+ Boolean = ActiveModel::Type::Boolean
51
+ Decimal = ActiveModel::Type::Decimal
52
+ DecimalWithoutScale = ActiveModel::Type::DecimalWithoutScale
53
+ Float = ActiveModel::Type::Float
54
+ Integer = ActiveModel::Type::Integer
55
+ String = ActiveModel::Type::String
56
+ Text = ActiveModel::Type::Text
57
+ UnsignedInteger = ActiveModel::Type::UnsignedInteger
58
+ Value = ActiveModel::Type::Value
59
+
60
+ register(:big_integer, Type::BigInteger, override: false)
61
+ register(:binary, Type::Binary, override: false)
62
+ register(:boolean, Type::Boolean, override: false)
63
+ register(:date, Type::Date, override: false)
64
+ register(:date_time, Type::DateTime, override: false)
65
+ register(:decimal, Type::Decimal, override: false)
66
+ register(:float, Type::Float, override: false)
67
+ register(:integer, Type::Integer, override: false)
68
+ register(:string, Type::String, override: false)
69
+ register(:text, Type::Text, override: false)
70
+ register(:time, Type::Time, override: false)
71
+ end
72
+ end
@@ -0,0 +1,130 @@
1
+ require 'active_model/type/registry'
2
+
3
+ module ActiveRecord
4
+ # :stopdoc:
5
+ module Type
6
+ class AdapterSpecificRegistry < ActiveModel::Type::Registry
7
+ def add_modifier(options, klass, **args)
8
+ registrations << DecorationRegistration.new(options, klass, **args)
9
+ end
10
+
11
+ private
12
+
13
+ def registration_klass
14
+ Registration
15
+ end
16
+
17
+ def find_registration(symbol, *args)
18
+ registrations
19
+ .select { |registration| registration.matches?(symbol, *args) }
20
+ .max
21
+ end
22
+ end
23
+
24
+ class Registration
25
+ def initialize(name, block, adapter: nil, override: nil)
26
+ @name = name
27
+ @block = block
28
+ @adapter = adapter
29
+ @override = override
30
+ end
31
+
32
+ def call(_registry, *args, adapter: nil, **kwargs)
33
+ if kwargs.any? # https://bugs.ruby-lang.org/issues/10856
34
+ block.call(*args, **kwargs)
35
+ else
36
+ block.call(*args)
37
+ end
38
+ end
39
+
40
+ def matches?(type_name, *args, **kwargs)
41
+ type_name == name && matches_adapter?(**kwargs)
42
+ end
43
+
44
+ def <=>(other)
45
+ if conflicts_with?(other)
46
+ raise TypeConflictError.new("Type #{name} was registered for all
47
+ adapters, but shadows a native type with
48
+ the same name for #{other.adapter}".squish)
49
+ end
50
+ priority <=> other.priority
51
+ end
52
+
53
+ protected
54
+
55
+ attr_reader :name, :block, :adapter, :override
56
+
57
+ def priority
58
+ result = 0
59
+ if adapter
60
+ result |= 1
61
+ end
62
+ if override
63
+ result |= 2
64
+ end
65
+ result
66
+ end
67
+
68
+ def priority_except_adapter
69
+ priority & 0b111111100
70
+ end
71
+
72
+ private
73
+
74
+ def matches_adapter?(adapter: nil, **)
75
+ (self.adapter.nil? || adapter == self.adapter)
76
+ end
77
+
78
+ def conflicts_with?(other)
79
+ same_priority_except_adapter?(other) &&
80
+ has_adapter_conflict?(other)
81
+ end
82
+
83
+ def same_priority_except_adapter?(other)
84
+ priority_except_adapter == other.priority_except_adapter
85
+ end
86
+
87
+ def has_adapter_conflict?(other)
88
+ (override.nil? && other.adapter) ||
89
+ (adapter && other.override.nil?)
90
+ end
91
+ end
92
+
93
+ class DecorationRegistration < Registration
94
+ def initialize(options, klass, adapter: nil)
95
+ @options = options
96
+ @klass = klass
97
+ @adapter = adapter
98
+ end
99
+
100
+ def call(registry, *args, **kwargs)
101
+ subtype = registry.lookup(*args, **kwargs.except(*options.keys))
102
+ klass.new(subtype)
103
+ end
104
+
105
+ def matches?(*args, **kwargs)
106
+ matches_adapter?(**kwargs) && matches_options?(**kwargs)
107
+ end
108
+
109
+ def priority
110
+ super | 4
111
+ end
112
+
113
+ protected
114
+
115
+ attr_reader :options, :klass
116
+
117
+ private
118
+
119
+ def matches_options?(**kwargs)
120
+ options.all? do |key, value|
121
+ kwargs[key] == value
122
+ end
123
+ end
124
+ end
125
+ end
126
+
127
+ class TypeConflictError < StandardError
128
+ end
129
+ # :startdoc:
130
+ end
@@ -1,50 +1,7 @@
1
1
  module ActiveRecord
2
2
  module Type
3
- class Date < Value # :nodoc:
4
- def type
5
- :date
6
- end
7
-
8
- def klass
9
- ::Date
10
- end
11
-
12
- def type_cast_for_database(value)
13
- type_cast(value)
14
- end
15
-
16
- def type_cast_for_schema(value)
17
- "'#{value.to_s(:db)}'"
18
- end
19
-
20
- private
21
-
22
- def cast_value(value)
23
- if value.is_a?(::String)
24
- return if value.empty?
25
- fast_string_to_date(value) || fallback_string_to_date(value)
26
- elsif value.respond_to?(:to_date)
27
- value.to_date
28
- else
29
- value
30
- end
31
- end
32
-
33
- def fast_string_to_date(string)
34
- if string =~ ConnectionAdapters::Column::Format::ISO_DATE
35
- new_date $1.to_i, $2.to_i, $3.to_i
36
- end
37
- end
38
-
39
- def fallback_string_to_date(string)
40
- new_date(*::Date._parse(string, false).values_at(:year, :mon, :mday))
41
- end
42
-
43
- def new_date(year, mon, mday)
44
- if year && year != 0
45
- ::Date.new(year, mon, mday) rescue nil
46
- end
47
- end
3
+ class Date < ActiveModel::Type::Date
4
+ include Internal::Timezone
48
5
  end
49
6
  end
50
7
  end
@@ -1,54 +1,7 @@
1
1
  module ActiveRecord
2
2
  module Type
3
- class DateTime < Value # :nodoc:
4
- include TimeValue
5
-
6
- def type
7
- :datetime
8
- end
9
-
10
- def type_cast_for_database(value)
11
- return super unless value.acts_like?(:time)
12
-
13
- zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
14
-
15
- if value.respond_to?(zone_conversion_method)
16
- value = value.send(zone_conversion_method)
17
- end
18
-
19
- return value unless has_precision?
20
-
21
- result = value.to_s(:db)
22
- if value.respond_to?(:usec) && (1..6).cover?(precision)
23
- "#{result}.#{sprintf("%0#{precision}d", value.usec / 10 ** (6 - precision))}"
24
- else
25
- result
26
- end
27
- end
28
-
29
- private
30
-
31
- alias has_precision? precision
32
-
33
- def cast_value(string)
34
- return string unless string.is_a?(::String)
35
- return if string.empty?
36
-
37
- fast_string_to_time(string) || fallback_string_to_time(string)
38
- end
39
-
40
- # '0.123456' -> 123456
41
- # '1.123456' -> 123456
42
- def microseconds(time)
43
- time[:sec_fraction] ? (time[:sec_fraction] * 1_000_000).to_i : 0
44
- end
45
-
46
- def fallback_string_to_time(string)
47
- time_hash = ::Date._parse(string)
48
- time_hash[:sec_fraction] = microseconds(time_hash)
49
-
50
- new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :offset))
51
- end
3
+ class DateTime < ActiveModel::Type::DateTime
4
+ include Internal::Timezone
52
5
  end
53
6
  end
54
7
  end
@@ -0,0 +1,33 @@
1
+ module ActiveRecord
2
+ module Type
3
+ module Internal # :nodoc:
4
+ class AbstractJson < ActiveModel::Type::Value # :nodoc:
5
+ include ActiveModel::Type::Helpers::Mutable
6
+
7
+ def type
8
+ :json
9
+ end
10
+
11
+ def deserialize(value)
12
+ if value.is_a?(::String)
13
+ ::ActiveSupport::JSON.decode(value) rescue nil
14
+ else
15
+ value
16
+ end
17
+ end
18
+
19
+ def serialize(value)
20
+ if value.is_a?(::Array) || value.is_a?(::Hash)
21
+ ::ActiveSupport::JSON.encode(value)
22
+ else
23
+ value
24
+ end
25
+ end
26
+
27
+ def accessor
28
+ ActiveRecord::Store::StringKeyedHashAccessor
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,15 @@
1
+ module ActiveRecord
2
+ module Type
3
+ module Internal
4
+ module Timezone
5
+ def is_utc?
6
+ ActiveRecord::Base.default_timezone == :utc
7
+ end
8
+
9
+ def default_timezone
10
+ ActiveRecord::Base.default_timezone
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,8 +1,7 @@
1
1
  module ActiveRecord
2
2
  module Type
3
- class Serialized < DelegateClass(Type::Value) # :nodoc:
4
- include Mutable
5
- include Decorator
3
+ class Serialized < DelegateClass(ActiveModel::Type::Value) # :nodoc:
4
+ include ActiveModel::Type::Helpers::Mutable
6
5
 
7
6
  attr_reader :subtype, :coder
8
7
 
@@ -12,7 +11,7 @@ module ActiveRecord
12
11
  super(subtype)
13
12
  end
14
13
 
15
- def type_cast_from_database(value)
14
+ def deserialize(value)
16
15
  if default_value?(value)
17
16
  value
18
17
  else
@@ -20,7 +19,7 @@ module ActiveRecord
20
19
  end
21
20
  end
22
21
 
23
- def type_cast_for_database(value)
22
+ def serialize(value)
24
23
  return if value.nil?
25
24
  unless default_value?(value)
26
25
  super coder.dump(value)
@@ -33,7 +32,7 @@ module ActiveRecord
33
32
 
34
33
  def changed_in_place?(raw_old_value, value)
35
34
  return false if value.nil?
36
- raw_new_value = type_cast_for_database(value)
35
+ raw_new_value = serialize(value)
37
36
  raw_old_value.nil? != raw_new_value.nil? ||
38
37
  subtype.changed_in_place?(raw_old_value, raw_new_value)
39
38
  end
@@ -42,14 +41,10 @@ module ActiveRecord
42
41
  ActiveRecord::Store::IndifferentHashAccessor
43
42
  end
44
43
 
45
- def init_with(coder)
46
- @coder = coder['coder']
47
- super
48
- end
49
-
50
- def encode_with(coder)
51
- coder['coder'] = @coder
52
- super
44
+ def assert_valid_value(value)
45
+ if coder.respond_to?(:assert_valid_value)
46
+ coder.assert_valid_value(value)
47
+ end
53
48
  end
54
49
 
55
50
  private
@@ -1,26 +1,8 @@
1
1
  module ActiveRecord
2
2
  module Type
3
- class Time < Value # :nodoc:
4
- include TimeValue
5
-
6
- def type
7
- :time
8
- end
9
-
10
- private
11
-
12
- def cast_value(value)
13
- return value unless value.is_a?(::String)
14
- return if value.empty?
15
-
16
- dummy_time_value = "2000-01-01 #{value}"
17
-
18
- fast_string_to_time(dummy_time_value) || begin
19
- time_hash = ::Date._parse(dummy_time_value)
20
- return if time_hash[:hour].nil?
21
- new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction))
22
- end
23
- end
3
+ class Time < ActiveModel::Type::Time
4
+ include Internal::Timezone
24
5
  end
25
6
  end
26
7
  end
8
+