activerecord 4.2.9 → 6.1.4.1

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 (374) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +964 -1382
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +15 -14
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/aggregations.rb +266 -251
  8. data/lib/active_record/association_relation.rb +40 -15
  9. data/lib/active_record/associations/alias_tracker.rb +40 -43
  10. data/lib/active_record/associations/association.rb +162 -69
  11. data/lib/active_record/associations/association_scope.rb +105 -130
  12. data/lib/active_record/associations/belongs_to_association.rb +83 -65
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
  14. data/lib/active_record/associations/builder/association.rb +57 -43
  15. data/lib/active_record/associations/builder/belongs_to.rb +74 -57
  16. data/lib/active_record/associations/builder/collection_association.rb +15 -37
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +49 -66
  18. data/lib/active_record/associations/builder/has_many.rb +13 -5
  19. data/lib/active_record/associations/builder/has_one.rb +44 -6
  20. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  21. data/lib/active_record/associations/collection_association.rb +148 -287
  22. data/lib/active_record/associations/collection_proxy.rb +252 -150
  23. data/lib/active_record/associations/foreign_association.rb +23 -1
  24. data/lib/active_record/associations/has_many_association.rb +56 -98
  25. data/lib/active_record/associations/has_many_through_association.rb +68 -89
  26. data/lib/active_record/associations/has_one_association.rb +73 -47
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +54 -81
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  31. data/lib/active_record/associations/join_dependency.rb +174 -169
  32. data/lib/active_record/associations/preloader/association.rb +108 -115
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +97 -94
  35. data/lib/active_record/associations/singular_association.rb +18 -39
  36. data/lib/active_record/associations/through_association.rb +39 -19
  37. data/lib/active_record/associations.rb +1845 -1598
  38. data/lib/active_record/attribute_assignment.rb +59 -185
  39. data/lib/active_record/attribute_methods/before_type_cast.rb +18 -10
  40. data/lib/active_record/attribute_methods/dirty.rb +168 -148
  41. data/lib/active_record/attribute_methods/primary_key.rb +93 -83
  42. data/lib/active_record/attribute_methods/query.rb +8 -10
  43. data/lib/active_record/attribute_methods/read.rb +19 -79
  44. data/lib/active_record/attribute_methods/serialization.rb +49 -24
  45. data/lib/active_record/attribute_methods/time_zone_conversion.rb +55 -36
  46. data/lib/active_record/attribute_methods/write.rb +24 -55
  47. data/lib/active_record/attribute_methods.rb +149 -154
  48. data/lib/active_record/attributes.rb +234 -78
  49. data/lib/active_record/autosave_association.rb +133 -60
  50. data/lib/active_record/base.rb +46 -46
  51. data/lib/active_record/callbacks.rb +234 -79
  52. data/lib/active_record/coders/json.rb +3 -1
  53. data/lib/active_record/coders/yaml_column.rb +34 -13
  54. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +887 -323
  55. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -41
  56. data/lib/active_record/connection_adapters/abstract/database_statements.rb +292 -124
  57. data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -24
  58. data/lib/active_record/connection_adapters/abstract/quoting.rb +177 -60
  59. data/lib/active_record/connection_adapters/abstract/savepoints.rb +8 -6
  60. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +157 -93
  61. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +473 -255
  62. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  63. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +869 -286
  64. data/lib/active_record/connection_adapters/abstract/transaction.rb +257 -91
  65. data/lib/active_record/connection_adapters/abstract_adapter.rb +483 -230
  66. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +557 -640
  67. data/lib/active_record/connection_adapters/column.rb +67 -40
  68. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  69. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  70. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  71. data/lib/active_record/connection_adapters/mysql/database_statements.rb +194 -0
  72. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  73. data/lib/active_record/connection_adapters/mysql/quoting.rb +96 -0
  74. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +97 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +103 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +91 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
  78. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
  79. data/lib/active_record/connection_adapters/mysql2_adapter.rb +80 -192
  80. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  81. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +44 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +75 -160
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +49 -58
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +4 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +8 -6
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -19
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -20
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  98. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  101. data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +70 -34
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  109. data/lib/active_record/connection_adapters/postgresql/oid.rb +25 -25
  110. data/lib/active_record/connection_adapters/postgresql/quoting.rb +145 -48
  111. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  112. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  114. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
  115. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +496 -298
  116. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +44 -0
  117. data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
  118. data/lib/active_record/connection_adapters/postgresql_adapter.rb +588 -375
  119. data/lib/active_record/connection_adapters/schema_cache.rb +167 -29
  120. data/lib/active_record/connection_adapters/sql_type_metadata.rb +45 -0
  121. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
  122. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  123. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +21 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  126. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  127. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
  128. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +322 -373
  129. data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
  130. data/lib/active_record/connection_adapters.rb +52 -0
  131. data/lib/active_record/connection_handling.rb +314 -41
  132. data/lib/active_record/core.rb +458 -241
  133. data/lib/active_record/counter_cache.rb +70 -49
  134. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  135. data/lib/active_record/database_configurations/database_config.rb +80 -0
  136. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  137. data/lib/active_record/database_configurations/url_config.rb +53 -0
  138. data/lib/active_record/database_configurations.rb +272 -0
  139. data/lib/active_record/delegated_type.rb +209 -0
  140. data/lib/active_record/destroy_association_async_job.rb +36 -0
  141. data/lib/active_record/dynamic_matchers.rb +87 -106
  142. data/lib/active_record/enum.rb +211 -92
  143. data/lib/active_record/errors.rb +224 -54
  144. data/lib/active_record/explain.rb +27 -11
  145. data/lib/active_record/explain_registry.rb +4 -2
  146. data/lib/active_record/explain_subscriber.rb +10 -5
  147. data/lib/active_record/fixture_set/file.rb +33 -14
  148. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  149. data/lib/active_record/fixture_set/render_context.rb +17 -0
  150. data/lib/active_record/fixture_set/table_row.rb +152 -0
  151. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  152. data/lib/active_record/fixtures.rb +275 -500
  153. data/lib/active_record/gem_version.rb +6 -4
  154. data/lib/active_record/inheritance.rb +175 -110
  155. data/lib/active_record/insert_all.rb +212 -0
  156. data/lib/active_record/integration.rb +121 -29
  157. data/lib/active_record/internal_metadata.rb +62 -0
  158. data/lib/active_record/legacy_yaml_adapter.rb +27 -5
  159. data/lib/active_record/locale/en.yml +3 -2
  160. data/lib/active_record/locking/optimistic.rb +98 -92
  161. data/lib/active_record/locking/pessimistic.rb +22 -6
  162. data/lib/active_record/log_subscriber.rb +93 -31
  163. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  164. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  165. data/lib/active_record/middleware/database_selector.rb +77 -0
  166. data/lib/active_record/migration/command_recorder.rb +185 -90
  167. data/lib/active_record/migration/compatibility.rb +295 -0
  168. data/lib/active_record/migration/join_table.rb +8 -7
  169. data/lib/active_record/migration.rb +673 -325
  170. data/lib/active_record/model_schema.rb +418 -113
  171. data/lib/active_record/nested_attributes.rb +263 -224
  172. data/lib/active_record/no_touching.rb +15 -2
  173. data/lib/active_record/null_relation.rb +24 -38
  174. data/lib/active_record/persistence.rb +572 -136
  175. data/lib/active_record/query_cache.rb +29 -23
  176. data/lib/active_record/querying.rb +50 -31
  177. data/lib/active_record/railtie.rb +170 -51
  178. data/lib/active_record/railties/console_sandbox.rb +3 -3
  179. data/lib/active_record/railties/controller_runtime.rb +34 -33
  180. data/lib/active_record/railties/databases.rake +523 -199
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +454 -291
  183. data/lib/active_record/relation/batches/batch_enumerator.rb +85 -0
  184. data/lib/active_record/relation/batches.rb +217 -59
  185. data/lib/active_record/relation/calculations.rb +324 -249
  186. data/lib/active_record/relation/delegation.rb +76 -84
  187. data/lib/active_record/relation/finder_methods.rb +316 -242
  188. data/lib/active_record/relation/from_clause.rb +30 -0
  189. data/lib/active_record/relation/merger.rb +95 -103
  190. data/lib/active_record/relation/predicate_builder/array_handler.rb +26 -26
  191. data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
  192. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  193. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +57 -0
  194. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  195. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  196. data/lib/active_record/relation/predicate_builder.rb +136 -122
  197. data/lib/active_record/relation/query_attribute.rb +50 -0
  198. data/lib/active_record/relation/query_methods.rb +757 -413
  199. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  200. data/lib/active_record/relation/spawn_methods.rb +18 -20
  201. data/lib/active_record/relation/where_clause.rb +239 -0
  202. data/lib/active_record/relation.rb +554 -343
  203. data/lib/active_record/result.rb +91 -47
  204. data/lib/active_record/runtime_registry.rb +6 -4
  205. data/lib/active_record/sanitization.rb +134 -122
  206. data/lib/active_record/schema.rb +21 -24
  207. data/lib/active_record/schema_dumper.rb +141 -92
  208. data/lib/active_record/schema_migration.rb +24 -23
  209. data/lib/active_record/scoping/default.rb +96 -83
  210. data/lib/active_record/scoping/named.rb +78 -36
  211. data/lib/active_record/scoping.rb +45 -27
  212. data/lib/active_record/secure_token.rb +48 -0
  213. data/lib/active_record/serialization.rb +8 -6
  214. data/lib/active_record/signed_id.rb +116 -0
  215. data/lib/active_record/statement_cache.rb +89 -36
  216. data/lib/active_record/store.rb +128 -43
  217. data/lib/active_record/suppressor.rb +61 -0
  218. data/lib/active_record/table_metadata.rb +81 -0
  219. data/lib/active_record/tasks/database_tasks.rb +364 -130
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +67 -113
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +86 -49
  222. data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -19
  223. data/lib/active_record/test_databases.rb +24 -0
  224. data/lib/active_record/test_fixtures.rb +287 -0
  225. data/lib/active_record/timestamp.rb +86 -43
  226. data/lib/active_record/touch_later.rb +65 -0
  227. data/lib/active_record/transactions.rb +182 -163
  228. data/lib/active_record/translation.rb +3 -1
  229. data/lib/active_record/type/adapter_specific_registry.rb +126 -0
  230. data/lib/active_record/type/date.rb +4 -45
  231. data/lib/active_record/type/date_time.rb +4 -49
  232. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  233. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  234. data/lib/active_record/type/internal/timezone.rb +17 -0
  235. data/lib/active_record/type/json.rb +30 -0
  236. data/lib/active_record/type/serialized.rb +27 -15
  237. data/lib/active_record/type/text.rb +2 -2
  238. data/lib/active_record/type/time.rb +21 -16
  239. data/lib/active_record/type/type_map.rb +16 -19
  240. data/lib/active_record/type/unsigned_integer.rb +9 -8
  241. data/lib/active_record/type.rb +84 -23
  242. data/lib/active_record/type_caster/connection.rb +33 -0
  243. data/lib/active_record/type_caster/map.rb +23 -0
  244. data/lib/active_record/type_caster.rb +9 -0
  245. data/lib/active_record/validations/absence.rb +25 -0
  246. data/lib/active_record/validations/associated.rb +12 -4
  247. data/lib/active_record/validations/length.rb +26 -0
  248. data/lib/active_record/validations/numericality.rb +35 -0
  249. data/lib/active_record/validations/presence.rb +14 -13
  250. data/lib/active_record/validations/uniqueness.rb +63 -56
  251. data/lib/active_record/validations.rb +39 -35
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/active_record.rb +42 -29
  254. data/lib/arel/alias_predication.rb +9 -0
  255. data/lib/arel/attributes/attribute.rb +41 -0
  256. data/lib/arel/collectors/bind.rb +29 -0
  257. data/lib/arel/collectors/composite.rb +39 -0
  258. data/lib/arel/collectors/plain_string.rb +20 -0
  259. data/lib/arel/collectors/sql_string.rb +27 -0
  260. data/lib/arel/collectors/substitute_binds.rb +35 -0
  261. data/lib/arel/crud.rb +42 -0
  262. data/lib/arel/delete_manager.rb +18 -0
  263. data/lib/arel/errors.rb +9 -0
  264. data/lib/arel/expressions.rb +29 -0
  265. data/lib/arel/factory_methods.rb +49 -0
  266. data/lib/arel/insert_manager.rb +49 -0
  267. data/lib/arel/math.rb +45 -0
  268. data/lib/arel/nodes/and.rb +32 -0
  269. data/lib/arel/nodes/ascending.rb +23 -0
  270. data/lib/arel/nodes/binary.rb +126 -0
  271. data/lib/arel/nodes/bind_param.rb +44 -0
  272. data/lib/arel/nodes/case.rb +55 -0
  273. data/lib/arel/nodes/casted.rb +62 -0
  274. data/lib/arel/nodes/comment.rb +29 -0
  275. data/lib/arel/nodes/count.rb +12 -0
  276. data/lib/arel/nodes/delete_statement.rb +45 -0
  277. data/lib/arel/nodes/descending.rb +23 -0
  278. data/lib/arel/nodes/equality.rb +15 -0
  279. data/lib/arel/nodes/extract.rb +24 -0
  280. data/lib/arel/nodes/false.rb +16 -0
  281. data/lib/arel/nodes/full_outer_join.rb +8 -0
  282. data/lib/arel/nodes/function.rb +44 -0
  283. data/lib/arel/nodes/grouping.rb +11 -0
  284. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  285. data/lib/arel/nodes/in.rb +15 -0
  286. data/lib/arel/nodes/infix_operation.rb +92 -0
  287. data/lib/arel/nodes/inner_join.rb +8 -0
  288. data/lib/arel/nodes/insert_statement.rb +37 -0
  289. data/lib/arel/nodes/join_source.rb +20 -0
  290. data/lib/arel/nodes/matches.rb +18 -0
  291. data/lib/arel/nodes/named_function.rb +23 -0
  292. data/lib/arel/nodes/node.rb +51 -0
  293. data/lib/arel/nodes/node_expression.rb +13 -0
  294. data/lib/arel/nodes/ordering.rb +27 -0
  295. data/lib/arel/nodes/outer_join.rb +8 -0
  296. data/lib/arel/nodes/over.rb +15 -0
  297. data/lib/arel/nodes/regexp.rb +16 -0
  298. data/lib/arel/nodes/right_outer_join.rb +8 -0
  299. data/lib/arel/nodes/select_core.rb +67 -0
  300. data/lib/arel/nodes/select_statement.rb +41 -0
  301. data/lib/arel/nodes/sql_literal.rb +19 -0
  302. data/lib/arel/nodes/string_join.rb +11 -0
  303. data/lib/arel/nodes/table_alias.rb +31 -0
  304. data/lib/arel/nodes/terminal.rb +16 -0
  305. data/lib/arel/nodes/true.rb +16 -0
  306. data/lib/arel/nodes/unary.rb +44 -0
  307. data/lib/arel/nodes/unary_operation.rb +20 -0
  308. data/lib/arel/nodes/unqualified_column.rb +22 -0
  309. data/lib/arel/nodes/update_statement.rb +41 -0
  310. data/lib/arel/nodes/values_list.rb +9 -0
  311. data/lib/arel/nodes/window.rb +126 -0
  312. data/lib/arel/nodes/with.rb +11 -0
  313. data/lib/arel/nodes.rb +70 -0
  314. data/lib/arel/order_predications.rb +13 -0
  315. data/lib/arel/predications.rb +250 -0
  316. data/lib/arel/select_manager.rb +270 -0
  317. data/lib/arel/table.rb +118 -0
  318. data/lib/arel/tree_manager.rb +72 -0
  319. data/lib/arel/update_manager.rb +34 -0
  320. data/lib/arel/visitors/dot.rb +308 -0
  321. data/lib/arel/visitors/mysql.rb +93 -0
  322. data/lib/arel/visitors/postgresql.rb +120 -0
  323. data/lib/arel/visitors/sqlite.rb +38 -0
  324. data/lib/arel/visitors/to_sql.rb +899 -0
  325. data/lib/arel/visitors/visitor.rb +45 -0
  326. data/lib/arel/visitors.rb +13 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +54 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  330. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +43 -37
  332. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +26 -0
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +13 -4
  334. data/lib/rails/generators/active_record/migration.rb +35 -1
  335. data/lib/rails/generators/active_record/model/model_generator.rb +55 -22
  336. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  337. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  338. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  339. data/lib/rails/generators/active_record.rb +7 -5
  340. metadata +172 -65
  341. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  342. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  343. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  344. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  345. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  346. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  347. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  348. data/lib/active_record/attribute.rb +0 -163
  349. data/lib/active_record/attribute_decorators.rb +0 -66
  350. data/lib/active_record/attribute_set/builder.rb +0 -106
  351. data/lib/active_record/attribute_set.rb +0 -81
  352. data/lib/active_record/connection_adapters/connection_specification.rb +0 -275
  353. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  354. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  355. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  356. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  357. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  358. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  359. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  360. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  361. data/lib/active_record/type/big_integer.rb +0 -13
  362. data/lib/active_record/type/binary.rb +0 -50
  363. data/lib/active_record/type/boolean.rb +0 -31
  364. data/lib/active_record/type/decimal.rb +0 -64
  365. data/lib/active_record/type/decorator.rb +0 -14
  366. data/lib/active_record/type/float.rb +0 -19
  367. data/lib/active_record/type/integer.rb +0 -59
  368. data/lib/active_record/type/mutable.rb +0 -16
  369. data/lib/active_record/type/numeric.rb +0 -36
  370. data/lib/active_record/type/string.rb +0 -40
  371. data/lib/active_record/type/time_value.rb +0 -38
  372. data/lib/active_record/type/value.rb +0 -110
  373. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
  374. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -0,0 +1,287 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/enumerable"
4
+
5
+ module ActiveRecord
6
+ module TestFixtures
7
+ extend ActiveSupport::Concern
8
+
9
+ def before_setup # :nodoc:
10
+ setup_fixtures
11
+ super
12
+ end
13
+
14
+ def after_teardown # :nodoc:
15
+ super
16
+ teardown_fixtures
17
+ end
18
+
19
+ included do
20
+ class_attribute :fixture_path, instance_writer: false
21
+ class_attribute :fixture_table_names, default: []
22
+ class_attribute :fixture_class_names, default: {}
23
+ class_attribute :use_transactional_tests, default: true
24
+ class_attribute :use_instantiated_fixtures, default: false # true, false, or :no_instances
25
+ class_attribute :pre_loaded_fixtures, default: false
26
+ class_attribute :lock_threads, default: true
27
+ end
28
+
29
+ module ClassMethods
30
+ # Sets the model class for a fixture when the class name cannot be inferred from the fixture name.
31
+ #
32
+ # Examples:
33
+ #
34
+ # set_fixture_class some_fixture: SomeModel,
35
+ # 'namespaced/fixture' => Another::Model
36
+ #
37
+ # The keys must be the fixture names, that coincide with the short paths to the fixture files.
38
+ def set_fixture_class(class_names = {})
39
+ self.fixture_class_names = fixture_class_names.merge(class_names.stringify_keys)
40
+ end
41
+
42
+ def fixtures(*fixture_set_names)
43
+ if fixture_set_names.first == :all
44
+ raise StandardError, "No fixture path found. Please set `#{self}.fixture_path`." if fixture_path.blank?
45
+ fixture_set_names = Dir[::File.join(fixture_path, "{**,*}/*.{yml}")].uniq
46
+ fixture_set_names.reject! { |f| f.start_with?(file_fixture_path.to_s) } if defined?(file_fixture_path) && file_fixture_path
47
+ fixture_set_names.map! { |f| f[fixture_path.to_s.size..-5].delete_prefix("/") }
48
+ else
49
+ fixture_set_names = fixture_set_names.flatten.map(&:to_s)
50
+ end
51
+
52
+ self.fixture_table_names |= fixture_set_names
53
+ setup_fixture_accessors(fixture_set_names)
54
+ end
55
+
56
+ def setup_fixture_accessors(fixture_set_names = nil)
57
+ fixture_set_names = Array(fixture_set_names || fixture_table_names)
58
+ methods = Module.new do
59
+ fixture_set_names.each do |fs_name|
60
+ fs_name = fs_name.to_s
61
+ accessor_name = fs_name.tr("/", "_").to_sym
62
+
63
+ define_method(accessor_name) do |*fixture_names|
64
+ force_reload = fixture_names.pop if fixture_names.last == true || fixture_names.last == :reload
65
+ return_single_record = fixture_names.size == 1
66
+ fixture_names = @loaded_fixtures[fs_name].fixtures.keys if fixture_names.empty?
67
+
68
+ @fixture_cache[fs_name] ||= {}
69
+
70
+ instances = fixture_names.map do |f_name|
71
+ f_name = f_name.to_s if f_name.is_a?(Symbol)
72
+ @fixture_cache[fs_name].delete(f_name) if force_reload
73
+
74
+ if @loaded_fixtures[fs_name][f_name]
75
+ @fixture_cache[fs_name][f_name] ||= @loaded_fixtures[fs_name][f_name].find
76
+ else
77
+ raise StandardError, "No fixture named '#{f_name}' found for fixture set '#{fs_name}'"
78
+ end
79
+ end
80
+
81
+ return_single_record ? instances.first : instances
82
+ end
83
+ private accessor_name
84
+ end
85
+ end
86
+ include methods
87
+ end
88
+
89
+ def uses_transaction(*methods)
90
+ @uses_transaction = [] unless defined?(@uses_transaction)
91
+ @uses_transaction.concat methods.map(&:to_s)
92
+ end
93
+
94
+ def uses_transaction?(method)
95
+ @uses_transaction = [] unless defined?(@uses_transaction)
96
+ @uses_transaction.include?(method.to_s)
97
+ end
98
+ end
99
+
100
+ def run_in_transaction?
101
+ use_transactional_tests &&
102
+ !self.class.uses_transaction?(name)
103
+ end
104
+
105
+ def setup_fixtures(config = ActiveRecord::Base)
106
+ if pre_loaded_fixtures && !use_transactional_tests
107
+ raise RuntimeError, "pre_loaded_fixtures requires use_transactional_tests"
108
+ end
109
+
110
+ @fixture_cache = {}
111
+ @fixture_connections = []
112
+ @@already_loaded_fixtures ||= {}
113
+ @connection_subscriber = nil
114
+ @legacy_saved_pool_configs = Hash.new { |hash, key| hash[key] = {} }
115
+ @saved_pool_configs = Hash.new { |hash, key| hash[key] = {} }
116
+
117
+ # Load fixtures once and begin transaction.
118
+ if run_in_transaction?
119
+ if @@already_loaded_fixtures[self.class]
120
+ @loaded_fixtures = @@already_loaded_fixtures[self.class]
121
+ else
122
+ @loaded_fixtures = load_fixtures(config)
123
+ @@already_loaded_fixtures[self.class] = @loaded_fixtures
124
+ end
125
+
126
+ # Begin transactions for connections already established
127
+ @fixture_connections = enlist_fixture_connections
128
+ @fixture_connections.each do |connection|
129
+ connection.begin_transaction joinable: false, _lazy: false
130
+ connection.pool.lock_thread = true if lock_threads
131
+ end
132
+
133
+ # When connections are established in the future, begin a transaction too
134
+ @connection_subscriber = ActiveSupport::Notifications.subscribe("!connection.active_record") do |_, _, _, _, payload|
135
+ spec_name = payload[:spec_name] if payload.key?(:spec_name)
136
+ shard = payload[:shard] if payload.key?(:shard)
137
+ setup_shared_connection_pool
138
+
139
+ if spec_name
140
+ begin
141
+ connection = ActiveRecord::Base.connection_handler.retrieve_connection(spec_name, shard: shard)
142
+ rescue ConnectionNotEstablished
143
+ connection = nil
144
+ end
145
+
146
+ if connection && !@fixture_connections.include?(connection)
147
+ connection.begin_transaction joinable: false, _lazy: false
148
+ connection.pool.lock_thread = true if lock_threads
149
+ @fixture_connections << connection
150
+ end
151
+ end
152
+ end
153
+
154
+ # Load fixtures for every test.
155
+ else
156
+ ActiveRecord::FixtureSet.reset_cache
157
+ @@already_loaded_fixtures[self.class] = nil
158
+ @loaded_fixtures = load_fixtures(config)
159
+ end
160
+
161
+ # Instantiate fixtures for every test if requested.
162
+ instantiate_fixtures if use_instantiated_fixtures
163
+ end
164
+
165
+ def teardown_fixtures
166
+ # Rollback changes if a transaction is active.
167
+ if run_in_transaction?
168
+ ActiveSupport::Notifications.unsubscribe(@connection_subscriber) if @connection_subscriber
169
+ @fixture_connections.each do |connection|
170
+ connection.rollback_transaction if connection.transaction_open?
171
+ connection.pool.lock_thread = false
172
+ end
173
+ @fixture_connections.clear
174
+ teardown_shared_connection_pool
175
+ else
176
+ ActiveRecord::FixtureSet.reset_cache
177
+ end
178
+
179
+ ActiveRecord::Base.clear_active_connections!
180
+ end
181
+
182
+ def enlist_fixture_connections
183
+ setup_shared_connection_pool
184
+
185
+ ActiveRecord::Base.connection_handler.connection_pool_list.map(&:connection)
186
+ end
187
+
188
+ private
189
+ # Shares the writing connection pool with connections on
190
+ # other handlers.
191
+ #
192
+ # In an application with a primary and replica the test fixtures
193
+ # need to share a connection pool so that the reading connection
194
+ # can see data in the open transaction on the writing connection.
195
+ def setup_shared_connection_pool
196
+ if ActiveRecord::Base.legacy_connection_handling
197
+ writing_handler = ActiveRecord::Base.connection_handlers[ActiveRecord::Base.writing_role]
198
+
199
+ ActiveRecord::Base.connection_handlers.values.each do |handler|
200
+ if handler != writing_handler
201
+ handler.connection_pool_names.each do |name|
202
+ writing_pool_manager = writing_handler.send(:owner_to_pool_manager)[name]
203
+ return unless writing_pool_manager
204
+
205
+ pool_manager = handler.send(:owner_to_pool_manager)[name]
206
+ @legacy_saved_pool_configs[handler][name] ||= {}
207
+ pool_manager.shard_names.each do |shard_name|
208
+ writing_pool_config = writing_pool_manager.get_pool_config(nil, shard_name)
209
+ pool_config = pool_manager.get_pool_config(nil, shard_name)
210
+ next if pool_config == writing_pool_config
211
+
212
+ @legacy_saved_pool_configs[handler][name][shard_name] = pool_config
213
+ pool_manager.set_pool_config(nil, shard_name, writing_pool_config)
214
+ end
215
+ end
216
+ end
217
+ end
218
+ else
219
+ handler = ActiveRecord::Base.connection_handler
220
+
221
+ handler.connection_pool_names.each do |name|
222
+ pool_manager = handler.send(:owner_to_pool_manager)[name]
223
+ pool_manager.shard_names.each do |shard_name|
224
+ writing_pool_config = pool_manager.get_pool_config(ActiveRecord::Base.writing_role, shard_name)
225
+ @saved_pool_configs[name][shard_name] ||= {}
226
+ pool_manager.role_names.each do |role|
227
+ next unless pool_config = pool_manager.get_pool_config(role, shard_name)
228
+ next if pool_config == writing_pool_config
229
+
230
+ @saved_pool_configs[name][shard_name][role] = pool_config
231
+ pool_manager.set_pool_config(role, shard_name, writing_pool_config)
232
+ end
233
+ end
234
+ end
235
+ end
236
+ end
237
+
238
+ def teardown_shared_connection_pool
239
+ if ActiveRecord::Base.legacy_connection_handling
240
+ @legacy_saved_pool_configs.each_pair do |handler, names|
241
+ names.each_pair do |name, shards|
242
+ shards.each_pair do |shard_name, pool_config|
243
+ pool_manager = handler.send(:owner_to_pool_manager)[name]
244
+ pool_manager.set_pool_config(nil, shard_name, pool_config)
245
+ end
246
+ end
247
+ end
248
+ else
249
+ handler = ActiveRecord::Base.connection_handler
250
+
251
+ @saved_pool_configs.each_pair do |name, shards|
252
+ pool_manager = handler.send(:owner_to_pool_manager)[name]
253
+ shards.each_pair do |shard_name, roles|
254
+ roles.each_pair do |role, pool_config|
255
+ next unless pool_manager.get_pool_config(role, shard_name)
256
+
257
+ pool_manager.set_pool_config(role, shard_name, pool_config)
258
+ end
259
+ end
260
+ end
261
+ end
262
+
263
+ @legacy_saved_pool_configs.clear
264
+ @saved_pool_configs.clear
265
+ end
266
+
267
+ def load_fixtures(config)
268
+ ActiveRecord::FixtureSet.create_fixtures(fixture_path, fixture_table_names, fixture_class_names, config).index_by(&:name)
269
+ end
270
+
271
+ def instantiate_fixtures
272
+ if pre_loaded_fixtures
273
+ raise RuntimeError, "Load fixtures before instantiating them." if ActiveRecord::FixtureSet.all_loaded_fixtures.empty?
274
+ ActiveRecord::FixtureSet.instantiate_all_loaded_fixtures(self, load_instances?)
275
+ else
276
+ raise RuntimeError, "Load fixtures before instantiating them." if @loaded_fixtures.nil?
277
+ @loaded_fixtures.each_value do |fixture_set|
278
+ ActiveRecord::FixtureSet.instantiate_fixtures(self, fixture_set, load_instances?)
279
+ end
280
+ end
281
+ end
282
+
283
+ def load_instances?
284
+ use_instantiated_fixtures != :no_instances
285
+ end
286
+ end
287
+ end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
- # = Active Record Timestamp
4
+ # = Active Record \Timestamp
3
5
  #
4
6
  # Active Record automatically timestamps create and update operations if the
5
7
  # table has fields named <tt>created_at/created_on</tt> or
@@ -15,14 +17,25 @@ module ActiveRecord
15
17
  #
16
18
  # == Time Zone aware attributes
17
19
  #
18
- # By default, ActiveRecord::Base keeps all the datetime columns time zone aware by executing following code.
20
+ # Active Record keeps all the <tt>datetime</tt> and <tt>time</tt> columns
21
+ # timezone aware. By default, these values are stored in the database as UTC
22
+ # and converted back to the current <tt>Time.zone</tt> when pulled from the database.
23
+ #
24
+ # This feature can be turned off completely by setting:
25
+ #
26
+ # config.active_record.time_zone_aware_attributes = false
27
+ #
28
+ # You can also specify that only <tt>datetime</tt> columns should be time-zone
29
+ # aware (while <tt>time</tt> should not) by setting:
30
+ #
31
+ # ActiveRecord::Base.time_zone_aware_types = [:datetime]
19
32
  #
20
- # config.active_record.time_zone_aware_attributes = true
33
+ # You can also add database specific timezone aware types. For example, for PostgreSQL:
21
34
  #
22
- # This feature can easily be turned off by assigning value <tt>false</tt> .
35
+ # ActiveRecord::Base.time_zone_aware_types += [:tsrange, :tstzrange]
23
36
  #
24
- # If your attributes are time zone aware and you desire to skip time zone conversion to the current Time.zone
25
- # when reading certain attributes then you can do following:
37
+ # Finally, you can indicate specific attributes of a model for which time zone
38
+ # conversion should not applied, for instance by setting:
26
39
  #
27
40
  # class Topic < ActiveRecord::Base
28
41
  # self.skip_time_zone_conversion_for_attributes = [:written_on]
@@ -31,8 +44,7 @@ module ActiveRecord
31
44
  extend ActiveSupport::Concern
32
45
 
33
46
  included do
34
- class_attribute :record_timestamps
35
- self.record_timestamps = true
47
+ class_attribute :record_timestamps, default: true
36
48
  end
37
49
 
38
50
  def initialize_dup(other) # :nodoc:
@@ -40,81 +52,112 @@ module ActiveRecord
40
52
  clear_timestamp_attributes
41
53
  end
42
54
 
43
- private
55
+ module ClassMethods # :nodoc:
56
+ def touch_attributes_with_time(*names, time: nil)
57
+ attribute_names = timestamp_attributes_for_update_in_model
58
+ attribute_names |= names.map(&:to_s)
59
+ attribute_names.index_with(time || current_time_from_proper_timezone)
60
+ end
61
+
62
+ def timestamp_attributes_for_create_in_model
63
+ @timestamp_attributes_for_create_in_model ||=
64
+ (timestamp_attributes_for_create & column_names).freeze
65
+ end
44
66
 
67
+ def timestamp_attributes_for_update_in_model
68
+ @timestamp_attributes_for_update_in_model ||=
69
+ (timestamp_attributes_for_update & column_names).freeze
70
+ end
71
+
72
+ def all_timestamp_attributes_in_model
73
+ @all_timestamp_attributes_in_model ||=
74
+ (timestamp_attributes_for_create_in_model + timestamp_attributes_for_update_in_model).freeze
75
+ end
76
+
77
+ def current_time_from_proper_timezone
78
+ default_timezone == :utc ? Time.now.utc : Time.now
79
+ end
80
+
81
+ private
82
+ def timestamp_attributes_for_create
83
+ ["created_at", "created_on"].map! { |name| attribute_aliases[name] || name }
84
+ end
85
+
86
+ def timestamp_attributes_for_update
87
+ ["updated_at", "updated_on"].map! { |name| attribute_aliases[name] || name }
88
+ end
89
+
90
+ def reload_schema_from_cache
91
+ @timestamp_attributes_for_create_in_model = nil
92
+ @timestamp_attributes_for_update_in_model = nil
93
+ @all_timestamp_attributes_in_model = nil
94
+ super
95
+ end
96
+ end
97
+
98
+ private
45
99
  def _create_record
46
- if self.record_timestamps
100
+ if record_timestamps
47
101
  current_time = current_time_from_proper_timezone
48
102
 
49
- all_timestamp_attributes.each do |column|
50
- column = column.to_s
51
- if has_attribute?(column) && !attribute_present?(column)
52
- write_attribute(column, current_time)
53
- end
103
+ all_timestamp_attributes_in_model.each do |column|
104
+ _write_attribute(column, current_time) unless _read_attribute(column)
54
105
  end
55
106
  end
56
107
 
57
108
  super
58
109
  end
59
110
 
60
- def _update_record(*args)
61
- if should_record_timestamps?
111
+ def _update_record
112
+ if @_touch_record && should_record_timestamps?
62
113
  current_time = current_time_from_proper_timezone
63
114
 
64
115
  timestamp_attributes_for_update_in_model.each do |column|
65
- column = column.to_s
66
- next if attribute_changed?(column)
67
- write_attribute(column, current_time)
116
+ next if will_save_change_to_attribute?(column)
117
+ _write_attribute(column, current_time)
68
118
  end
69
119
  end
120
+
121
+ super
122
+ end
123
+
124
+ def create_or_update(touch: true, **)
125
+ @_touch_record = touch
70
126
  super
71
127
  end
72
128
 
73
129
  def should_record_timestamps?
74
- self.record_timestamps && (!partial_writes? || changed?)
130
+ record_timestamps && (!partial_writes? || has_changes_to_save?)
75
131
  end
76
132
 
77
133
  def timestamp_attributes_for_create_in_model
78
- timestamp_attributes_for_create.select { |c| self.class.column_names.include?(c.to_s) }
134
+ self.class.timestamp_attributes_for_create_in_model
79
135
  end
80
136
 
81
137
  def timestamp_attributes_for_update_in_model
82
- timestamp_attributes_for_update.select { |c| self.class.column_names.include?(c.to_s) }
138
+ self.class.timestamp_attributes_for_update_in_model
83
139
  end
84
140
 
85
141
  def all_timestamp_attributes_in_model
86
- timestamp_attributes_for_create_in_model + timestamp_attributes_for_update_in_model
142
+ self.class.all_timestamp_attributes_in_model
87
143
  end
88
144
 
89
- def timestamp_attributes_for_update
90
- [:updated_at, :updated_on]
91
- end
92
-
93
- def timestamp_attributes_for_create
94
- [:created_at, :created_on]
95
- end
96
-
97
- def all_timestamp_attributes
98
- timestamp_attributes_for_create + timestamp_attributes_for_update
145
+ def current_time_from_proper_timezone
146
+ self.class.current_time_from_proper_timezone
99
147
  end
100
148
 
101
- def max_updated_column_timestamp(timestamp_names = timestamp_attributes_for_update)
102
- timestamp_names
103
- .map { |attr| self[attr] }
149
+ def max_updated_column_timestamp
150
+ timestamp_attributes_for_update_in_model
151
+ .map { |attr| self[attr]&.to_time }
104
152
  .compact
105
- .map(&:to_time)
106
153
  .max
107
154
  end
108
155
 
109
- def current_time_from_proper_timezone
110
- self.class.default_timezone == :utc ? Time.now.utc : Time.now
111
- end
112
-
113
156
  # Clear attributes and changed_attributes
114
157
  def clear_timestamp_attributes
115
158
  all_timestamp_attributes_in_model.each do |attribute_name|
116
159
  self[attribute_name] = nil
117
- clear_attribute_changes([attribute_name])
160
+ clear_attribute_change(attribute_name)
118
161
  end
119
162
  end
120
163
  end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ # = Active Record Touch Later
5
+ module TouchLater # :nodoc:
6
+ def before_committed!
7
+ touch_deferred_attributes if has_defer_touch_attrs? && persisted?
8
+ super
9
+ end
10
+
11
+ def touch_later(*names) # :nodoc:
12
+ _raise_record_not_touched_error unless persisted?
13
+
14
+ @_defer_touch_attrs ||= timestamp_attributes_for_update_in_model
15
+ @_defer_touch_attrs |= names.map! do |name|
16
+ name = name.to_s
17
+ self.class.attribute_aliases[name] || name
18
+ end unless names.empty?
19
+
20
+ @_touch_time = current_time_from_proper_timezone
21
+
22
+ surreptitiously_touch @_defer_touch_attrs
23
+ add_to_transaction
24
+ @_new_record_before_last_commit ||= false
25
+
26
+ # touch the parents as we are not calling the after_save callbacks
27
+ self.class.reflect_on_all_associations(:belongs_to).each do |r|
28
+ if touch = r.options[:touch]
29
+ ActiveRecord::Associations::Builder::BelongsTo.touch_record(self, changes_to_save, r.foreign_key, r.name, touch, :touch_later)
30
+ end
31
+ end
32
+ end
33
+
34
+ def touch(*names, time: nil) # :nodoc:
35
+ if has_defer_touch_attrs?
36
+ names |= @_defer_touch_attrs
37
+ super(*names, time: time)
38
+ @_defer_touch_attrs, @_touch_time = nil, nil
39
+ else
40
+ super
41
+ end
42
+ end
43
+
44
+ private
45
+ def surreptitiously_touch(attr_names)
46
+ attr_names.each do |attr_name|
47
+ _write_attribute(attr_name, @_touch_time)
48
+ clear_attribute_change(attr_name)
49
+ end
50
+ end
51
+
52
+ def touch_deferred_attributes
53
+ @_skip_dirty_tracking = true
54
+ touch(time: @_touch_time)
55
+ end
56
+
57
+ def has_defer_touch_attrs?
58
+ defined?(@_defer_touch_attrs) && @_defer_touch_attrs.present?
59
+ end
60
+
61
+ def belongs_to_touch_method
62
+ :touch_later
63
+ end
64
+ end
65
+ end