activerecord 5.1.0 → 5.2.3

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 (261) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +596 -450
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -5
  5. data/examples/performance.rb +2 -0
  6. data/examples/simple.rb +2 -0
  7. data/lib/active_record.rb +11 -4
  8. data/lib/active_record/aggregations.rb +6 -5
  9. data/lib/active_record/association_relation.rb +7 -5
  10. data/lib/active_record/associations.rb +77 -85
  11. data/lib/active_record/associations/alias_tracker.rb +23 -32
  12. data/lib/active_record/associations/association.rb +49 -35
  13. data/lib/active_record/associations/association_scope.rb +55 -55
  14. data/lib/active_record/associations/belongs_to_association.rb +30 -11
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
  16. data/lib/active_record/associations/builder/association.rb +4 -7
  17. data/lib/active_record/associations/builder/belongs_to.rb +21 -8
  18. data/lib/active_record/associations/builder/collection_association.rb +1 -1
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
  20. data/lib/active_record/associations/builder/has_many.rb +2 -0
  21. data/lib/active_record/associations/builder/has_one.rb +2 -0
  22. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  23. data/lib/active_record/associations/collection_association.rb +66 -53
  24. data/lib/active_record/associations/collection_proxy.rb +30 -73
  25. data/lib/active_record/associations/foreign_association.rb +2 -0
  26. data/lib/active_record/associations/has_many_association.rb +13 -2
  27. data/lib/active_record/associations/has_many_through_association.rb +37 -19
  28. data/lib/active_record/associations/has_one_association.rb +14 -1
  29. data/lib/active_record/associations/has_one_through_association.rb +13 -8
  30. data/lib/active_record/associations/join_dependency.rb +52 -96
  31. data/lib/active_record/associations/join_dependency/join_association.rb +22 -75
  32. data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
  33. data/lib/active_record/associations/join_dependency/join_part.rb +9 -9
  34. data/lib/active_record/associations/preloader.rb +17 -37
  35. data/lib/active_record/associations/preloader/association.rb +53 -92
  36. data/lib/active_record/associations/preloader/through_association.rb +72 -73
  37. data/lib/active_record/associations/singular_association.rb +14 -16
  38. data/lib/active_record/associations/through_association.rb +27 -12
  39. data/lib/active_record/attribute_assignment.rb +2 -5
  40. data/lib/active_record/attribute_decorators.rb +3 -2
  41. data/lib/active_record/attribute_methods.rb +65 -24
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
  43. data/lib/active_record/attribute_methods/dirty.rb +33 -216
  44. data/lib/active_record/attribute_methods/primary_key.rb +10 -13
  45. data/lib/active_record/attribute_methods/query.rb +2 -0
  46. data/lib/active_record/attribute_methods/read.rb +9 -3
  47. data/lib/active_record/attribute_methods/serialization.rb +23 -0
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
  49. data/lib/active_record/attribute_methods/write.rb +22 -19
  50. data/lib/active_record/attributes.rb +7 -6
  51. data/lib/active_record/autosave_association.rb +15 -13
  52. data/lib/active_record/base.rb +2 -0
  53. data/lib/active_record/callbacks.rb +12 -6
  54. data/lib/active_record/coders/json.rb +2 -0
  55. data/lib/active_record/coders/yaml_column.rb +2 -0
  56. data/lib/active_record/collection_cache_key.rb +15 -11
  57. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +120 -39
  58. data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -0
  59. data/lib/active_record/connection_adapters/abstract/database_statements.rb +192 -37
  60. data/lib/active_record/connection_adapters/abstract/query_cache.rb +13 -2
  61. data/lib/active_record/connection_adapters/abstract/quoting.rb +15 -25
  62. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  63. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +15 -6
  64. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +65 -7
  65. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
  66. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +158 -87
  67. data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -21
  68. data/lib/active_record/connection_adapters/abstract_adapter.rb +86 -98
  69. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +126 -189
  70. data/lib/active_record/connection_adapters/column.rb +4 -2
  71. data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
  72. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +13 -2
  73. data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
  74. data/lib/active_record/connection_adapters/mysql/database_statements.rb +45 -15
  75. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
  76. data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
  77. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
  78. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -10
  79. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -23
  80. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -1
  81. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
  82. data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
  83. data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
  84. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -32
  85. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid.rb +3 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +13 -1
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  99. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
  101. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +8 -2
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  109. data/lib/active_record/connection_adapters/postgresql/quoting.rb +22 -1
  110. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  111. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +50 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
  113. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
  114. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +258 -129
  115. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
  116. data/lib/active_record/connection_adapters/postgresql/utils.rb +3 -1
  117. data/lib/active_record/connection_adapters/postgresql_adapter.rb +75 -87
  118. data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
  119. data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +24 -1
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +75 -1
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +90 -96
  127. data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
  128. data/lib/active_record/connection_handling.rb +4 -2
  129. data/lib/active_record/core.rb +41 -61
  130. data/lib/active_record/counter_cache.rb +20 -15
  131. data/lib/active_record/define_callbacks.rb +5 -3
  132. data/lib/active_record/dynamic_matchers.rb +9 -9
  133. data/lib/active_record/enum.rb +18 -13
  134. data/lib/active_record/errors.rb +60 -15
  135. data/lib/active_record/explain.rb +3 -1
  136. data/lib/active_record/explain_registry.rb +2 -0
  137. data/lib/active_record/explain_subscriber.rb +2 -0
  138. data/lib/active_record/fixture_set/file.rb +2 -0
  139. data/lib/active_record/fixtures.rb +67 -60
  140. data/lib/active_record/gem_version.rb +4 -2
  141. data/lib/active_record/inheritance.rb +49 -19
  142. data/lib/active_record/integration.rb +58 -19
  143. data/lib/active_record/internal_metadata.rb +2 -0
  144. data/lib/active_record/legacy_yaml_adapter.rb +3 -1
  145. data/lib/active_record/locking/optimistic.rb +30 -42
  146. data/lib/active_record/locking/pessimistic.rb +10 -7
  147. data/lib/active_record/log_subscriber.rb +46 -4
  148. data/lib/active_record/migration.rb +189 -139
  149. data/lib/active_record/migration/command_recorder.rb +11 -9
  150. data/lib/active_record/migration/compatibility.rb +81 -29
  151. data/lib/active_record/migration/join_table.rb +2 -0
  152. data/lib/active_record/model_schema.rb +74 -58
  153. data/lib/active_record/nested_attributes.rb +18 -6
  154. data/lib/active_record/no_touching.rb +3 -1
  155. data/lib/active_record/null_relation.rb +2 -0
  156. data/lib/active_record/persistence.rb +199 -54
  157. data/lib/active_record/query_cache.rb +8 -10
  158. data/lib/active_record/querying.rb +5 -3
  159. data/lib/active_record/railtie.rb +62 -6
  160. data/lib/active_record/railties/console_sandbox.rb +2 -0
  161. data/lib/active_record/railties/controller_runtime.rb +2 -0
  162. data/lib/active_record/railties/databases.rake +48 -38
  163. data/lib/active_record/readonly_attributes.rb +3 -2
  164. data/lib/active_record/reflection.rb +137 -207
  165. data/lib/active_record/relation.rb +132 -207
  166. data/lib/active_record/relation/batches.rb +32 -17
  167. data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
  168. data/lib/active_record/relation/calculations.rb +66 -25
  169. data/lib/active_record/relation/delegation.rb +45 -29
  170. data/lib/active_record/relation/finder_methods.rb +76 -85
  171. data/lib/active_record/relation/from_clause.rb +2 -8
  172. data/lib/active_record/relation/merger.rb +53 -23
  173. data/lib/active_record/relation/predicate_builder.rb +60 -79
  174. data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
  175. data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
  176. data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
  177. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
  178. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
  179. data/lib/active_record/relation/predicate_builder/range_handler.rb +26 -9
  180. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  181. data/lib/active_record/relation/query_attribute.rb +28 -2
  182. data/lib/active_record/relation/query_methods.rb +135 -103
  183. data/lib/active_record/relation/record_fetch_warning.rb +2 -0
  184. data/lib/active_record/relation/spawn_methods.rb +4 -2
  185. data/lib/active_record/relation/where_clause.rb +65 -67
  186. data/lib/active_record/relation/where_clause_factory.rb +5 -48
  187. data/lib/active_record/result.rb +2 -0
  188. data/lib/active_record/runtime_registry.rb +2 -0
  189. data/lib/active_record/sanitization.rb +129 -121
  190. data/lib/active_record/schema.rb +4 -2
  191. data/lib/active_record/schema_dumper.rb +36 -26
  192. data/lib/active_record/schema_migration.rb +2 -0
  193. data/lib/active_record/scoping.rb +12 -10
  194. data/lib/active_record/scoping/default.rb +10 -7
  195. data/lib/active_record/scoping/named.rb +40 -12
  196. data/lib/active_record/secure_token.rb +2 -0
  197. data/lib/active_record/serialization.rb +2 -0
  198. data/lib/active_record/statement_cache.rb +22 -12
  199. data/lib/active_record/store.rb +3 -1
  200. data/lib/active_record/suppressor.rb +2 -0
  201. data/lib/active_record/table_metadata.rb +12 -3
  202. data/lib/active_record/tasks/database_tasks.rb +38 -26
  203. data/lib/active_record/tasks/mysql_database_tasks.rb +11 -50
  204. data/lib/active_record/tasks/postgresql_database_tasks.rb +11 -3
  205. data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
  206. data/lib/active_record/timestamp.rb +13 -6
  207. data/lib/active_record/touch_later.rb +2 -0
  208. data/lib/active_record/transactions.rb +32 -27
  209. data/lib/active_record/translation.rb +2 -0
  210. data/lib/active_record/type.rb +4 -1
  211. data/lib/active_record/type/adapter_specific_registry.rb +2 -0
  212. data/lib/active_record/type/date.rb +2 -0
  213. data/lib/active_record/type/date_time.rb +2 -0
  214. data/lib/active_record/type/decimal_without_scale.rb +2 -0
  215. data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
  216. data/lib/active_record/type/internal/timezone.rb +2 -0
  217. data/lib/active_record/type/json.rb +30 -0
  218. data/lib/active_record/type/serialized.rb +6 -0
  219. data/lib/active_record/type/text.rb +2 -0
  220. data/lib/active_record/type/time.rb +2 -0
  221. data/lib/active_record/type/type_map.rb +2 -0
  222. data/lib/active_record/type/unsigned_integer.rb +2 -0
  223. data/lib/active_record/type_caster.rb +2 -0
  224. data/lib/active_record/type_caster/connection.rb +2 -0
  225. data/lib/active_record/type_caster/map.rb +3 -1
  226. data/lib/active_record/validations.rb +2 -0
  227. data/lib/active_record/validations/absence.rb +2 -0
  228. data/lib/active_record/validations/associated.rb +2 -0
  229. data/lib/active_record/validations/length.rb +2 -0
  230. data/lib/active_record/validations/presence.rb +2 -0
  231. data/lib/active_record/validations/uniqueness.rb +36 -6
  232. data/lib/active_record/version.rb +2 -0
  233. data/lib/rails/generators/active_record.rb +3 -1
  234. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  235. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  236. data/lib/rails/generators/active_record/migration.rb +2 -0
  237. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
  238. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
  239. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
  240. data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
  241. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
  242. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  243. metadata +24 -36
  244. data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
  245. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  246. data/lib/active_record/associations/preloader/has_many.rb +0 -15
  247. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  248. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  249. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  250. data/lib/active_record/associations/preloader/singular_association.rb +0 -18
  251. data/lib/active_record/attribute.rb +0 -240
  252. data/lib/active_record/attribute/user_provided_default.rb +0 -30
  253. data/lib/active_record/attribute_mutation_tracker.rb +0 -113
  254. data/lib/active_record/attribute_set.rb +0 -113
  255. data/lib/active_record/attribute_set/builder.rb +0 -124
  256. data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
  257. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
  258. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  259. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  260. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
  261. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,15 +0,0 @@
1
- module ActiveRecord
2
- module Associations
3
- class Preloader
4
- class BelongsTo < SingularAssociation #:nodoc:
5
- def association_key_name
6
- reflection.options[:primary_key] || klass && klass.primary_key
7
- end
8
-
9
- def owner_key_name
10
- reflection.foreign_key
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,17 +0,0 @@
1
- module ActiveRecord
2
- module Associations
3
- class Preloader
4
- class CollectionAssociation < Association #:nodoc:
5
- private
6
-
7
- def preload(preloader)
8
- associated_records_by_owner(preloader).each do |owner, records|
9
- association = owner.association(reflection.name)
10
- association.loaded!
11
- association.target.concat(records)
12
- end
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,15 +0,0 @@
1
- module ActiveRecord
2
- module Associations
3
- class Preloader
4
- class HasMany < CollectionAssociation #:nodoc:
5
- def association_key_name
6
- reflection.foreign_key
7
- end
8
-
9
- def owner_key_name
10
- reflection.active_record_primary_key
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,19 +0,0 @@
1
- module ActiveRecord
2
- module Associations
3
- class Preloader
4
- class HasManyThrough < CollectionAssociation #:nodoc:
5
- include ThroughAssociation
6
-
7
- def associated_records_by_owner(preloader)
8
- records_by_owner = super
9
-
10
- if reflection_scope.distinct_value
11
- records_by_owner.each_value(&:uniq!)
12
- end
13
-
14
- records_by_owner
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,15 +0,0 @@
1
- module ActiveRecord
2
- module Associations
3
- class Preloader
4
- class HasOne < SingularAssociation #:nodoc:
5
- def association_key_name
6
- reflection.foreign_key
7
- end
8
-
9
- def owner_key_name
10
- reflection.active_record_primary_key
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,9 +0,0 @@
1
- module ActiveRecord
2
- module Associations
3
- class Preloader
4
- class HasOneThrough < SingularAssociation #:nodoc:
5
- include ThroughAssociation
6
- end
7
- end
8
- end
9
- end
@@ -1,18 +0,0 @@
1
- module ActiveRecord
2
- module Associations
3
- class Preloader
4
- class SingularAssociation < Association #:nodoc:
5
- private
6
-
7
- def preload(preloader)
8
- associated_records_by_owner(preloader).each do |owner, associated_records|
9
- record = associated_records.first
10
-
11
- association = owner.association(reflection.name)
12
- association.target = record
13
- end
14
- end
15
- end
16
- end
17
- end
18
- end
@@ -1,240 +0,0 @@
1
- module ActiveRecord
2
- class Attribute # :nodoc:
3
- class << self
4
- def from_database(name, value, type)
5
- FromDatabase.new(name, value, type)
6
- end
7
-
8
- def from_user(name, value, type, original_attribute = nil)
9
- FromUser.new(name, value, type, original_attribute)
10
- end
11
-
12
- def with_cast_value(name, value, type)
13
- WithCastValue.new(name, value, type)
14
- end
15
-
16
- def null(name)
17
- Null.new(name)
18
- end
19
-
20
- def uninitialized(name, type)
21
- Uninitialized.new(name, type)
22
- end
23
- end
24
-
25
- attr_reader :name, :value_before_type_cast, :type
26
-
27
- # This method should not be called directly.
28
- # Use #from_database or #from_user
29
- def initialize(name, value_before_type_cast, type, original_attribute = nil)
30
- @name = name
31
- @value_before_type_cast = value_before_type_cast
32
- @type = type
33
- @original_attribute = original_attribute
34
- end
35
-
36
- def value
37
- # `defined?` is cheaper than `||=` when we get back falsy values
38
- @value = type_cast(value_before_type_cast) unless defined?(@value)
39
- @value
40
- end
41
-
42
- def original_value
43
- if assigned?
44
- original_attribute.original_value
45
- else
46
- type_cast(value_before_type_cast)
47
- end
48
- end
49
-
50
- def value_for_database
51
- type.serialize(value)
52
- end
53
-
54
- def changed?
55
- changed_from_assignment? || changed_in_place?
56
- end
57
-
58
- def changed_in_place?
59
- has_been_read? && type.changed_in_place?(original_value_for_database, value)
60
- end
61
-
62
- def forgetting_assignment
63
- with_value_from_database(value_for_database)
64
- end
65
-
66
- def with_value_from_user(value)
67
- type.assert_valid_value(value)
68
- self.class.from_user(name, value, type, original_attribute || self)
69
- end
70
-
71
- def with_value_from_database(value)
72
- self.class.from_database(name, value, type)
73
- end
74
-
75
- def with_cast_value(value)
76
- self.class.with_cast_value(name, value, type)
77
- end
78
-
79
- def with_type(type)
80
- if changed_in_place?
81
- with_value_from_user(value).with_type(type)
82
- else
83
- self.class.new(name, value_before_type_cast, type, original_attribute)
84
- end
85
- end
86
-
87
- def type_cast(*)
88
- raise NotImplementedError
89
- end
90
-
91
- def initialized?
92
- true
93
- end
94
-
95
- def came_from_user?
96
- false
97
- end
98
-
99
- def has_been_read?
100
- defined?(@value)
101
- end
102
-
103
- def ==(other)
104
- self.class == other.class &&
105
- name == other.name &&
106
- value_before_type_cast == other.value_before_type_cast &&
107
- type == other.type
108
- end
109
- alias eql? ==
110
-
111
- def hash
112
- [self.class, name, value_before_type_cast, type].hash
113
- end
114
-
115
- def init_with(coder)
116
- @name = coder["name"]
117
- @value_before_type_cast = coder["value_before_type_cast"]
118
- @type = coder["type"]
119
- @original_attribute = coder["original_attribute"]
120
- @value = coder["value"] if coder.map.key?("value")
121
- end
122
-
123
- def encode_with(coder)
124
- coder["name"] = name
125
- coder["value_before_type_cast"] = value_before_type_cast if value_before_type_cast
126
- coder["type"] = type if type
127
- coder["original_attribute"] = original_attribute if original_attribute
128
- coder["value"] = value if defined?(@value)
129
- end
130
-
131
- # TODO Change this to private once we've dropped Ruby 2.2 support.
132
- # Workaround for Ruby 2.2 "private attribute?" warning.
133
- protected
134
-
135
- attr_reader :original_attribute
136
- alias_method :assigned?, :original_attribute
137
-
138
- def original_value_for_database
139
- if assigned?
140
- original_attribute.original_value_for_database
141
- else
142
- _original_value_for_database
143
- end
144
- end
145
-
146
- private
147
- def initialize_dup(other)
148
- if defined?(@value) && @value.duplicable?
149
- @value = @value.dup
150
- end
151
- end
152
-
153
- def changed_from_assignment?
154
- assigned? && type.changed?(original_value, value, value_before_type_cast)
155
- end
156
-
157
- def _original_value_for_database
158
- type.serialize(original_value)
159
- end
160
-
161
- class FromDatabase < Attribute # :nodoc:
162
- def type_cast(value)
163
- type.deserialize(value)
164
- end
165
-
166
- def _original_value_for_database
167
- value_before_type_cast
168
- end
169
- end
170
-
171
- class FromUser < Attribute # :nodoc:
172
- def type_cast(value)
173
- type.cast(value)
174
- end
175
-
176
- def came_from_user?
177
- true
178
- end
179
- end
180
-
181
- class WithCastValue < Attribute # :nodoc:
182
- def type_cast(value)
183
- value
184
- end
185
-
186
- def changed_in_place?
187
- false
188
- end
189
- end
190
-
191
- class Null < Attribute # :nodoc:
192
- def initialize(name)
193
- super(name, nil, Type.default_value)
194
- end
195
-
196
- def type_cast(*)
197
- nil
198
- end
199
-
200
- def with_type(type)
201
- self.class.with_cast_value(name, nil, type)
202
- end
203
-
204
- def with_value_from_database(value)
205
- raise ActiveModel::MissingAttributeError, "can't write unknown attribute `#{name}`"
206
- end
207
- alias_method :with_value_from_user, :with_value_from_database
208
- end
209
-
210
- class Uninitialized < Attribute # :nodoc:
211
- UNINITIALIZED_ORIGINAL_VALUE = Object.new
212
-
213
- def initialize(name, type)
214
- super(name, nil, type)
215
- end
216
-
217
- def value
218
- if block_given?
219
- yield name
220
- end
221
- end
222
-
223
- def original_value
224
- UNINITIALIZED_ORIGINAL_VALUE
225
- end
226
-
227
- def value_for_database
228
- end
229
-
230
- def initialized?
231
- false
232
- end
233
-
234
- def with_type(type)
235
- self.class.new(name, type)
236
- end
237
- end
238
- private_constant :FromDatabase, :FromUser, :Null, :Uninitialized, :WithCastValue
239
- end
240
- end
@@ -1,30 +0,0 @@
1
- require "active_record/attribute"
2
-
3
- module ActiveRecord
4
- class Attribute # :nodoc:
5
- class UserProvidedDefault < FromUser # :nodoc:
6
- def initialize(name, value, type, database_default)
7
- @user_provided_value = value
8
- super(name, value, type, database_default)
9
- end
10
-
11
- def value_before_type_cast
12
- if user_provided_value.is_a?(Proc)
13
- @memoized_value_before_type_cast ||= user_provided_value.call
14
- else
15
- @user_provided_value
16
- end
17
- end
18
-
19
- def with_type(type)
20
- self.class.new(name, user_provided_value, type, original_attribute)
21
- end
22
-
23
- # TODO Change this to private once we've dropped Ruby 2.2 support.
24
- # Workaround for Ruby 2.2 "private attribute?" warning.
25
- protected
26
-
27
- attr_reader :user_provided_value
28
- end
29
- end
30
- end
@@ -1,113 +0,0 @@
1
- module ActiveRecord
2
- class AttributeMutationTracker # :nodoc:
3
- OPTION_NOT_GIVEN = Object.new
4
-
5
- def initialize(attributes)
6
- @attributes = attributes
7
- @forced_changes = Set.new
8
- @deprecated_forced_changes = Set.new
9
- end
10
-
11
- def changed_values
12
- attr_names.each_with_object({}.with_indifferent_access) do |attr_name, result|
13
- if changed?(attr_name)
14
- result[attr_name] = attributes[attr_name].original_value
15
- end
16
- end
17
- end
18
-
19
- def changes
20
- attr_names.each_with_object({}.with_indifferent_access) do |attr_name, result|
21
- change = change_to_attribute(attr_name)
22
- if change
23
- result[attr_name] = change
24
- end
25
- end
26
- end
27
-
28
- def change_to_attribute(attr_name)
29
- if changed?(attr_name)
30
- [attributes[attr_name].original_value, attributes.fetch_value(attr_name)]
31
- end
32
- end
33
-
34
- def any_changes?
35
- attr_names.any? { |attr| changed?(attr) } || deprecated_forced_changes.any?
36
- end
37
-
38
- def changed?(attr_name, from: OPTION_NOT_GIVEN, to: OPTION_NOT_GIVEN)
39
- attr_name = attr_name.to_s
40
- forced_changes.include?(attr_name) ||
41
- attributes[attr_name].changed? &&
42
- (OPTION_NOT_GIVEN == from || attributes[attr_name].original_value == from) &&
43
- (OPTION_NOT_GIVEN == to || attributes[attr_name].value == to)
44
- end
45
-
46
- def changed_in_place?(attr_name)
47
- attributes[attr_name].changed_in_place?
48
- end
49
-
50
- def forget_change(attr_name)
51
- attr_name = attr_name.to_s
52
- attributes[attr_name] = attributes[attr_name].forgetting_assignment
53
- forced_changes.delete(attr_name)
54
- end
55
-
56
- def original_value(attr_name)
57
- attributes[attr_name].original_value
58
- end
59
-
60
- def force_change(attr_name)
61
- forced_changes << attr_name.to_s
62
- end
63
-
64
- def deprecated_force_change(attr_name)
65
- deprecated_forced_changes << attr_name.to_s
66
- end
67
-
68
- # TODO Change this to private once we've dropped Ruby 2.2 support.
69
- # Workaround for Ruby 2.2 "private attribute?" warning.
70
- protected
71
-
72
- attr_reader :attributes, :forced_changes, :deprecated_forced_changes
73
-
74
- private
75
-
76
- def attr_names
77
- attributes.keys
78
- end
79
- end
80
-
81
- class NullMutationTracker # :nodoc:
82
- include Singleton
83
-
84
- def changed_values(*)
85
- {}
86
- end
87
-
88
- def changes(*)
89
- {}
90
- end
91
-
92
- def change_to_attribute(attr_name)
93
- end
94
-
95
- def any_changes?(*)
96
- false
97
- end
98
-
99
- def changed?(*)
100
- false
101
- end
102
-
103
- def changed_in_place?(*)
104
- false
105
- end
106
-
107
- def forget_change(*)
108
- end
109
-
110
- def original_value(*)
111
- end
112
- end
113
- end