activerecord 4.2.11.1 → 6.0.3.5

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