activerecord 4.2.0 → 6.0.5.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 (373) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +852 -801
  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 +267 -249
  9. data/lib/active_record/association_relation.rb +26 -6
  10. data/lib/active_record/associations/alias_tracker.rb +29 -36
  11. data/lib/active_record/associations/association.rb +137 -55
  12. data/lib/active_record/associations/association_scope.rb +110 -132
  13. data/lib/active_record/associations/belongs_to_association.rb +67 -54
  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 -29
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +58 -70
  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 +150 -275
  23. data/lib/active_record/associations/collection_proxy.rb +253 -152
  24. data/lib/active_record/associations/foreign_association.rb +20 -0
  25. data/lib/active_record/associations/has_many_association.rb +35 -84
  26. data/lib/active_record/associations/has_many_through_association.rb +62 -80
  27. data/lib/active_record/associations/has_one_association.rb +62 -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 +43 -78
  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 +159 -162
  33. data/lib/active_record/associations/preloader/association.rb +102 -113
  34. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  35. data/lib/active_record/associations/preloader.rb +96 -95
  36. data/lib/active_record/associations/singular_association.rb +18 -45
  37. data/lib/active_record/associations/through_association.rb +49 -24
  38. data/lib/active_record/associations.rb +1737 -1596
  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 +14 -5
  42. data/lib/active_record/attribute_methods/dirty.rb +174 -134
  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 +61 -37
  48. data/lib/active_record/attribute_methods/write.rb +33 -56
  49. data/lib/active_record/attribute_methods.rb +124 -143
  50. data/lib/active_record/attributes.rb +213 -74
  51. data/lib/active_record/autosave_association.rb +125 -54
  52. data/lib/active_record/base.rb +60 -49
  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 +36 -13
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +810 -291
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +253 -108
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +83 -24
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +171 -53
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +6 -4
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -47
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +383 -239
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +736 -235
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +190 -87
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +487 -192
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +536 -600
  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 +268 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +59 -196
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +71 -115
  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 -57
  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 +5 -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 +17 -13
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +6 -3
  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 +70 -34
  102. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +67 -51
  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 +465 -291
  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 +565 -363
  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 -364
  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 +277 -233
  130. data/lib/active_record/counter_cache.rb +71 -50
  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 +172 -89
  138. data/lib/active_record/errors.rb +189 -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 +11 -6
  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 +225 -497
  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 +48 -0
  154. data/lib/active_record/locale/en.yml +3 -2
  155. data/lib/active_record/locking/optimistic.rb +99 -98
  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 +636 -290
  165. data/lib/active_record/model_schema.rb +344 -112
  166. data/lib/active_record/nested_attributes.rb +265 -215
  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 +559 -125
  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 +166 -47
  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 +341 -202
  177. data/lib/active_record/readonly_attributes.rb +5 -4
  178. data/lib/active_record/reflection.rb +461 -302
  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 +270 -249
  182. data/lib/active_record/relation/delegation.rb +76 -84
  183. data/lib/active_record/relation/finder_methods.rb +287 -255
  184. data/lib/active_record/relation/from_clause.rb +30 -0
  185. data/lib/active_record/relation/merger.rb +86 -68
  186. data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -25
  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 +112 -92
  194. data/lib/active_record/relation/query_attribute.rb +50 -0
  195. data/lib/active_record/relation/query_methods.rb +612 -392
  196. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  197. data/lib/active_record/relation/spawn_methods.rb +18 -17
  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 +533 -340
  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 -20
  207. data/lib/active_record/scoping/default.rb +98 -82
  208. data/lib/active_record/scoping/named.rb +91 -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 +309 -99
  217. data/lib/active_record/tasks/mysql_database_tasks.rb +58 -89
  218. data/lib/active_record/tasks/postgresql_database_tasks.rb +81 -31
  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 +243 -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 +222 -146
  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 -41
  228. data/lib/active_record/type/date_time.rb +4 -38
  229. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  230. data/lib/active_record/type/hash_lookup_type_map.rb +12 -5
  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 +29 -15
  234. data/lib/active_record/type/text.rb +2 -2
  235. data/lib/active_record/type/time.rb +21 -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 +43 -46
  247. data/lib/active_record/validations.rb +38 -35
  248. data/lib/active_record/version.rb +3 -1
  249. data/lib/active_record.rb +44 -21
  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 -8
  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.rb +7 -5
  340. metadata +174 -63
  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 -149
  349. data/lib/active_record/attribute_set/builder.rb +0 -86
  350. data/lib/active_record/attribute_set.rb +0 -77
  351. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  352. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  353. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  354. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  355. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  356. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  357. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  358. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  359. data/lib/active_record/type/big_integer.rb +0 -13
  360. data/lib/active_record/type/binary.rb +0 -50
  361. data/lib/active_record/type/boolean.rb +0 -30
  362. data/lib/active_record/type/decimal.rb +0 -40
  363. data/lib/active_record/type/decorator.rb +0 -14
  364. data/lib/active_record/type/float.rb +0 -19
  365. data/lib/active_record/type/integer.rb +0 -55
  366. data/lib/active_record/type/mutable.rb +0 -16
  367. data/lib/active_record/type/numeric.rb +0 -36
  368. data/lib/active_record/type/string.rb +0 -36
  369. data/lib/active_record/type/time_value.rb +0 -38
  370. data/lib/active_record/type/value.rb +0 -101
  371. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
  372. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
  373. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -0,0 +1,243 @@
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
+ @saved_pool_configs = Hash.new { |hash, key| hash[key] = {} }
116
+
117
+ if @@already_loaded_fixtures[self.class]
118
+ @loaded_fixtures = @@already_loaded_fixtures[self.class]
119
+ else
120
+ @loaded_fixtures = load_fixtures(config)
121
+ @@already_loaded_fixtures[self.class] = @loaded_fixtures
122
+ end
123
+
124
+ # Begin transactions for connections already established
125
+ @fixture_connections = enlist_fixture_connections
126
+ @fixture_connections.each do |connection|
127
+ connection.begin_transaction joinable: false, _lazy: false
128
+ connection.pool.lock_thread = true if lock_threads
129
+ end
130
+
131
+ # When connections are established in the future, begin a transaction too
132
+ @connection_subscriber = ActiveSupport::Notifications.subscribe("!connection.active_record") do |_, _, _, _, payload|
133
+ spec_name = payload[:spec_name] if payload.key?(:spec_name)
134
+ setup_shared_connection_pool
135
+
136
+ if spec_name
137
+ begin
138
+ connection = ActiveRecord::Base.connection_handler.retrieve_connection(spec_name)
139
+ rescue ConnectionNotEstablished
140
+ connection = nil
141
+ end
142
+
143
+ if connection && !@fixture_connections.include?(connection)
144
+ connection.begin_transaction joinable: false, _lazy: false
145
+ connection.pool.lock_thread = true if lock_threads
146
+ @fixture_connections << connection
147
+ end
148
+ end
149
+ end
150
+
151
+ # Load fixtures for every test.
152
+ else
153
+ ActiveRecord::FixtureSet.reset_cache
154
+ @@already_loaded_fixtures[self.class] = nil
155
+ @loaded_fixtures = load_fixtures(config)
156
+ end
157
+
158
+ # Instantiate fixtures for every test if requested.
159
+ instantiate_fixtures if use_instantiated_fixtures
160
+ end
161
+
162
+ def teardown_fixtures
163
+ # Rollback changes if a transaction is active.
164
+ if run_in_transaction?
165
+ ActiveSupport::Notifications.unsubscribe(@connection_subscriber) if @connection_subscriber
166
+ @fixture_connections.each do |connection|
167
+ connection.rollback_transaction if connection.transaction_open?
168
+ connection.pool.lock_thread = false
169
+ end
170
+ @fixture_connections.clear
171
+ teardown_shared_connection_pool
172
+ else
173
+ ActiveRecord::FixtureSet.reset_cache
174
+ end
175
+
176
+ ActiveRecord::Base.clear_active_connections!
177
+ end
178
+
179
+ def enlist_fixture_connections
180
+ setup_shared_connection_pool
181
+
182
+ ActiveRecord::Base.connection_handler.connection_pool_list.map(&:connection)
183
+ end
184
+
185
+ private
186
+ # Shares the writing connection pool with connections on
187
+ # other handlers.
188
+ #
189
+ # In an application with a primary and replica the test fixtures
190
+ # need to share a connection pool so that the reading connection
191
+ # can see data in the open transaction on the writing connection.
192
+ def setup_shared_connection_pool
193
+ writing_handler = ActiveRecord::Base.connection_handlers[ActiveRecord::Base.writing_role]
194
+
195
+ ActiveRecord::Base.connection_handlers.values.each do |handler|
196
+ if handler != writing_handler
197
+ handler.connection_pool_list.each do |pool|
198
+ name = pool.spec.name
199
+ writing_connection = writing_handler.retrieve_connection_pool(name)
200
+ return unless writing_connection
201
+
202
+ reading_connection = handler.send(:owner_to_pool)[name]
203
+ next if reading_connection == writing_connection
204
+
205
+ @saved_pool_configs[handler][name] = reading_connection
206
+ handler.send(:owner_to_pool)[name] = writing_connection
207
+ end
208
+ end
209
+ end
210
+ end
211
+
212
+ def teardown_shared_connection_pool
213
+ @saved_pool_configs.each_pair do |handler, pools|
214
+ pools.each_pair do |name, pool|
215
+ handler.send(:owner_to_pool)[name] = pool
216
+ end
217
+ end
218
+
219
+ @saved_pool_configs.clear
220
+ end
221
+
222
+ def load_fixtures(config)
223
+ fixtures = ActiveRecord::FixtureSet.create_fixtures(fixture_path, fixture_table_names, fixture_class_names, config)
224
+ Hash[fixtures.map { |f| [f.name, f] }]
225
+ end
226
+
227
+ def instantiate_fixtures
228
+ if pre_loaded_fixtures
229
+ raise RuntimeError, "Load fixtures before instantiating them." if ActiveRecord::FixtureSet.all_loaded_fixtures.empty?
230
+ ActiveRecord::FixtureSet.instantiate_all_loaded_fixtures(self, load_instances?)
231
+ else
232
+ raise RuntimeError, "Load fixtures before instantiating them." if @loaded_fixtures.nil?
233
+ @loaded_fixtures.each_value do |fixture_set|
234
+ ActiveRecord::FixtureSet.instantiate_fixtures(self, fixture_set, load_instances?)
235
+ end
236
+ end
237
+ end
238
+
239
+ def load_instances?
240
+ use_instantiated_fixtures != :no_instances
241
+ end
242
+ end
243
+ 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