activerecord 4.2.0 → 6.1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (374) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1221 -796
  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 +267 -249
  8. data/lib/active_record/association_relation.rb +45 -7
  9. data/lib/active_record/associations/alias_tracker.rb +40 -43
  10. data/lib/active_record/associations/association.rb +172 -67
  11. data/lib/active_record/associations/association_scope.rb +105 -129
  12. data/lib/active_record/associations/belongs_to_association.rb +85 -59
  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 -33
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +57 -70
  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 +168 -279
  22. data/lib/active_record/associations/collection_proxy.rb +263 -155
  23. data/lib/active_record/associations/foreign_association.rb +33 -0
  24. data/lib/active_record/associations/has_many_association.rb +57 -84
  25. data/lib/active_record/associations/has_many_through_association.rb +70 -82
  26. data/lib/active_record/associations/has_one_association.rb +74 -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 -73
  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 +175 -164
  32. data/lib/active_record/associations/preloader/association.rb +107 -112
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +99 -96
  35. data/lib/active_record/associations/singular_association.rb +18 -45
  36. data/lib/active_record/associations/through_association.rb +49 -24
  37. data/lib/active_record/associations.rb +1845 -1597
  38. data/lib/active_record/attribute_assignment.rb +59 -185
  39. data/lib/active_record/attribute_methods/before_type_cast.rb +20 -7
  40. data/lib/active_record/attribute_methods/dirty.rb +168 -138
  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 +59 -36
  46. data/lib/active_record/attribute_methods/write.rb +25 -56
  47. data/lib/active_record/attribute_methods.rb +153 -162
  48. data/lib/active_record/attributes.rb +234 -70
  49. data/lib/active_record/autosave_association.rb +157 -69
  50. data/lib/active_record/base.rb +49 -50
  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 +46 -13
  54. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +887 -317
  55. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -41
  56. data/lib/active_record/connection_adapters/abstract/database_statements.rb +301 -113
  57. data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -24
  58. data/lib/active_record/connection_adapters/abstract/quoting.rb +187 -60
  59. data/lib/active_record/connection_adapters/abstract/savepoints.rb +9 -7
  60. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +157 -93
  61. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +485 -253
  62. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  63. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +909 -263
  64. data/lib/active_record/connection_adapters/abstract/transaction.rb +254 -92
  65. data/lib/active_record/connection_adapters/abstract_adapter.rb +492 -221
  66. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +580 -608
  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 +196 -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 +271 -0
  78. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
  79. data/lib/active_record/connection_adapters/mysql2_adapter.rb +81 -199
  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 +78 -161
  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 +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 +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/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 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +67 -51
  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 +171 -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 +499 -293
  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 +595 -382
  119. data/lib/active_record/connection_adapters/schema_cache.rb +191 -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 +146 -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 -389
  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 +488 -243
  133. data/lib/active_record/counter_cache.rb +71 -50
  134. data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -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 +273 -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 +212 -94
  143. data/lib/active_record/errors.rb +225 -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 +11 -6
  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 +273 -496
  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 +64 -0
  158. data/lib/active_record/legacy_yaml_adapter.rb +52 -0
  159. data/lib/active_record/locale/en.yml +3 -2
  160. data/lib/active_record/locking/optimistic.rb +103 -95
  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 +298 -0
  168. data/lib/active_record/migration/join_table.rb +8 -7
  169. data/lib/active_record/migration.rb +685 -309
  170. data/lib/active_record/model_schema.rb +420 -113
  171. data/lib/active_record/nested_attributes.rb +265 -216
  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 +574 -135
  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 +175 -54
  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 +533 -216
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +485 -310
  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 +326 -244
  186. data/lib/active_record/relation/delegation.rb +76 -84
  187. data/lib/active_record/relation/finder_methods.rb +318 -256
  188. data/lib/active_record/relation/from_clause.rb +30 -0
  189. data/lib/active_record/relation/merger.rb +99 -84
  190. data/lib/active_record/relation/predicate_builder/array_handler.rb +26 -25
  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 +139 -96
  197. data/lib/active_record/relation/query_attribute.rb +50 -0
  198. data/lib/active_record/relation/query_methods.rb +757 -409
  199. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  200. data/lib/active_record/relation/spawn_methods.rb +23 -21
  201. data/lib/active_record/relation/where_clause.rb +239 -0
  202. data/lib/active_record/relation.rb +554 -342
  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 -26
  209. data/lib/active_record/scoping/default.rb +96 -82
  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 +133 -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 +366 -129
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +68 -100
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +87 -39
  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 +291 -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 +181 -152
  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 -41
  231. data/lib/active_record/type/date_time.rb +4 -38
  232. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  233. data/lib/active_record/type/hash_lookup_type_map.rb +12 -5
  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 +33 -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 +65 -48
  251. data/lib/active_record/validations.rb +39 -35
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/active_record.rb +44 -28
  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 -10
  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.rb +7 -5
  339. metadata +175 -65
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  342. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  343. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  344. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  347. data/lib/active_record/attribute.rb +0 -149
  348. data/lib/active_record/attribute_decorators.rb +0 -66
  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/connection_specification.rb +0 -275
  352. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  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 -30
  363. data/lib/active_record/type/decimal.rb +0 -40
  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 -55
  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 -36
  370. data/lib/active_record/type/time_value.rb +0 -38
  371. data/lib/active_record/type/value.rb +0 -101
  372. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
  373. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
  374. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class Relation
5
+ class FromClause # :nodoc:
6
+ attr_reader :value, :name
7
+
8
+ def initialize(value, name)
9
+ @value = value
10
+ @name = name
11
+ end
12
+
13
+ def merge(other)
14
+ self
15
+ end
16
+
17
+ def empty?
18
+ value.nil?
19
+ end
20
+
21
+ def ==(other)
22
+ self.class == other.class && value == other.value && name == other.name
23
+ end
24
+
25
+ def self.empty
26
+ @empty ||= new(nil, nil).freeze
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,20 +1,22 @@
1
- require 'active_support/core_ext/hash/keys'
2
- require "set"
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/keys"
3
4
 
4
5
  module ActiveRecord
5
6
  class Relation
6
7
  class HashMerger # :nodoc:
7
8
  attr_reader :relation, :hash
8
9
 
9
- def initialize(relation, hash)
10
+ def initialize(relation, hash, rewhere = nil)
10
11
  hash.assert_valid_keys(*Relation::VALUE_METHODS)
11
12
 
12
13
  @relation = relation
13
14
  @hash = hash
15
+ @rewhere = rewhere
14
16
  end
15
17
 
16
- def merge #:nodoc:
17
- Merger.new(relation, other).merge
18
+ def merge
19
+ Merger.new(relation, other, @rewhere).merge
18
20
  end
19
21
 
20
22
  # Applying values to a relation has some side effects. E.g.
@@ -22,20 +24,19 @@ module ActiveRecord
22
24
  # build a relation to merge in rather than directly merging
23
25
  # the values.
24
26
  def other
25
- other = Relation.create(relation.klass, relation.table)
26
- hash.each { |k, v|
27
- if k == :joins
28
- if Hash === v
29
- other.joins!(v)
30
- else
31
- other.joins!(*v)
32
- end
33
- elsif k == :select
34
- other._select!(v)
27
+ other = Relation.create(
28
+ relation.klass,
29
+ table: relation.table,
30
+ predicate_builder: relation.predicate_builder
31
+ )
32
+ hash.each do |k, v|
33
+ k = :_select if k == :select
34
+ if Array === v
35
+ other.public_send("#{k}!", *v)
35
36
  else
36
- other.send("#{k}!", v)
37
+ other.public_send("#{k}!", v)
37
38
  end
38
- }
39
+ end
39
40
  other
40
41
  end
41
42
  end
@@ -43,15 +44,16 @@ module ActiveRecord
43
44
  class Merger # :nodoc:
44
45
  attr_reader :relation, :values, :other
45
46
 
46
- def initialize(relation, other)
47
+ def initialize(relation, other, rewhere = nil)
47
48
  @relation = relation
48
49
  @values = other.values
49
50
  @other = other
51
+ @rewhere = rewhere
50
52
  end
51
53
 
52
- NORMAL_VALUES = Relation::SINGLE_VALUE_METHODS +
53
- Relation::MULTI_VALUE_METHODS -
54
- [:joins, :where, :order, :bind, :reverse_order, :lock, :create_with, :reordering, :from] # :nodoc:
54
+ NORMAL_VALUES = Relation::VALUE_METHODS -
55
+ Relation::CLAUSE_METHODS -
56
+ [:includes, :preload, :joins, :left_outer_joins, :order, :reverse_order, :lock, :create_with, :reordering] # :nodoc:
55
57
 
56
58
  def normal_values
57
59
  NORMAL_VALUES
@@ -68,103 +70,116 @@ module ActiveRecord
68
70
  if name == :select
69
71
  relation._select!(*value)
70
72
  else
71
- relation.send("#{name}!", *value)
73
+ relation.public_send("#{name}!", *value)
72
74
  end
73
75
  end
74
76
  end
75
77
 
76
78
  merge_multi_values
77
79
  merge_single_values
80
+ merge_clauses
81
+ merge_preloads
78
82
  merge_joins
83
+ merge_outer_joins
79
84
 
80
85
  relation
81
86
  end
82
87
 
83
88
  private
89
+ def merge_preloads
90
+ return if other.preload_values.empty? && other.includes_values.empty?
84
91
 
85
- def merge_joins
86
- return if other.joins_values.blank?
92
+ if other.klass == relation.klass
93
+ relation.preload_values |= other.preload_values unless other.preload_values.empty?
94
+ relation.includes_values |= other.includes_values unless other.includes_values.empty?
95
+ else
96
+ reflection = relation.klass.reflect_on_all_associations.find do |r|
97
+ r.class_name == other.klass.name
98
+ end || return
87
99
 
88
- if other.klass == relation.klass
89
- relation.joins!(*other.joins_values)
90
- else
91
- joins_dependency, rest = other.joins_values.partition do |join|
92
- case join
93
- when Hash, Symbol, Array
94
- true
95
- else
96
- false
100
+ unless other.preload_values.empty?
101
+ relation.preload! reflection.name => other.preload_values
97
102
  end
98
- end
99
103
 
100
- join_dependency = ActiveRecord::Associations::JoinDependency.new(other.klass,
101
- joins_dependency,
102
- [])
103
- relation.joins! rest
104
-
105
- @relation = relation.joins join_dependency
104
+ unless other.includes_values.empty?
105
+ relation.includes! reflection.name => other.includes_values
106
+ end
107
+ end
106
108
  end
107
- end
108
109
 
109
- def merge_multi_values
110
- lhs_wheres = relation.where_values
111
- rhs_wheres = other.where_values
110
+ def merge_joins
111
+ return if other.joins_values.empty?
112
112
 
113
- lhs_binds = relation.bind_values
114
- rhs_binds = other.bind_values
113
+ if other.klass == relation.klass
114
+ relation.joins_values |= other.joins_values
115
+ else
116
+ associations, others = other.joins_values.partition do |join|
117
+ case join
118
+ when Hash, Symbol, Array; true
119
+ end
120
+ end
115
121
 
116
- removed, kept = partition_overwrites(lhs_wheres, rhs_wheres)
122
+ join_dependency = other.construct_join_dependency(
123
+ associations, Arel::Nodes::InnerJoin
124
+ )
125
+ relation.joins!(join_dependency, *others)
126
+ end
127
+ end
117
128
 
118
- where_values = kept + rhs_wheres
119
- bind_values = filter_binds(lhs_binds, removed) + rhs_binds
129
+ def merge_outer_joins
130
+ return if other.left_outer_joins_values.empty?
120
131
 
121
- relation.where_values = where_values
122
- relation.bind_values = bind_values
132
+ if other.klass == relation.klass
133
+ relation.left_outer_joins_values |= other.left_outer_joins_values
134
+ else
135
+ associations, others = other.left_outer_joins_values.partition do |join|
136
+ case join
137
+ when Hash, Symbol, Array; true
138
+ end
139
+ end
123
140
 
124
- if other.reordering_value
125
- # override any order specified in the original relation
126
- relation.reorder! other.order_values
127
- elsif other.order_values
128
- # merge in order_values from relation
129
- relation.order! other.order_values
141
+ join_dependency = other.construct_join_dependency(
142
+ associations, Arel::Nodes::OuterJoin
143
+ )
144
+ relation.left_outer_joins!(join_dependency, *others)
145
+ end
130
146
  end
131
147
 
132
- relation.extend(*other.extending_values) unless other.extending_values.blank?
133
- end
134
-
135
- def merge_single_values
136
- relation.from_value = other.from_value unless relation.from_value
137
- relation.lock_value = other.lock_value unless relation.lock_value
148
+ def merge_multi_values
149
+ if other.reordering_value
150
+ # override any order specified in the original relation
151
+ relation.reorder!(*other.order_values)
152
+ elsif other.order_values.any?
153
+ # merge in order_values from relation
154
+ relation.order!(*other.order_values)
155
+ end
138
156
 
139
- unless other.create_with_value.blank?
140
- relation.create_with_value = (relation.create_with_value || {}).merge(other.create_with_value)
157
+ extensions = other.extensions - relation.extensions
158
+ relation.extending!(*extensions) if extensions.any?
141
159
  end
142
- end
143
-
144
- def filter_binds(lhs_binds, removed_wheres)
145
- return lhs_binds if removed_wheres.empty?
146
160
 
147
- set = Set.new removed_wheres.map { |x| x.left.name.to_s }
148
- lhs_binds.dup.delete_if { |col,_| set.include? col.name }
149
- end
161
+ def merge_single_values
162
+ relation.lock_value ||= other.lock_value if other.lock_value
150
163
 
151
- # Remove equalities from the existing relation with a LHS which is
152
- # present in the relation being merged in.
153
- # returns [things_to_remove, things_to_keep]
154
- def partition_overwrites(lhs_wheres, rhs_wheres)
155
- if lhs_wheres.empty? || rhs_wheres.empty?
156
- return [[], lhs_wheres]
164
+ unless other.create_with_value.blank?
165
+ relation.create_with_value = (relation.create_with_value || {}).merge(other.create_with_value)
166
+ end
157
167
  end
158
168
 
159
- nodes = rhs_wheres.find_all do |w|
160
- w.respond_to?(:operator) && w.operator == :==
169
+ def merge_clauses
170
+ relation.from_clause = other.from_clause if replace_from_clause?
171
+
172
+ where_clause = relation.where_clause.merge(other.where_clause, @rewhere)
173
+ relation.where_clause = where_clause unless where_clause.empty?
174
+
175
+ having_clause = relation.having_clause.merge(other.having_clause)
176
+ relation.having_clause = having_clause unless having_clause.empty?
161
177
  end
162
- seen = Set.new(nodes) { |node| node.left }
163
178
 
164
- lhs_wheres.partition do |w|
165
- w.respond_to?(:operator) && w.operator == :== && seen.include?(w.left)
179
+ def replace_from_clause?
180
+ relation.from_clause.empty? && !other.from_clause.empty? &&
181
+ relation.klass.base_class == other.klass.base_class
166
182
  end
167
- end
168
183
  end
169
184
  end
170
185
  end
@@ -1,47 +1,48 @@
1
- require 'active_support/core_ext/string/filters'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/array/extract"
2
4
 
3
5
  module ActiveRecord
4
6
  class PredicateBuilder
5
7
  class ArrayHandler # :nodoc:
6
- def call(attribute, value)
7
- values = value.map { |x| x.is_a?(Base) ? x.id : x }
8
- nils, values = values.partition(&:nil?)
9
-
10
- if values.any? { |val| val.is_a?(Array) }
11
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
12
- Passing a nested array to Active Record finder methods is
13
- deprecated and will be removed. Flatten your array before using
14
- it for 'IN' conditions.
15
- MSG
16
-
17
- values = values.flatten
18
- end
8
+ def initialize(predicate_builder)
9
+ @predicate_builder = predicate_builder
10
+ end
19
11
 
20
- return attribute.in([]) if values.empty? && nils.empty?
12
+ def call(attribute, value)
13
+ return attribute.in([]) if value.empty?
21
14
 
22
- ranges, values = values.partition { |v| v.is_a?(Range) }
15
+ values = value.map { |x| x.is_a?(Base) ? x.id : x }
16
+ nils = values.extract!(&:nil?)
17
+ ranges = values.extract! { |v| v.is_a?(Range) }
23
18
 
24
19
  values_predicate =
25
20
  case values.length
26
21
  when 0 then NullPredicate
27
- when 1 then attribute.eq(values.first)
28
- else attribute.in(values)
22
+ when 1 then predicate_builder.build(attribute, values.first)
23
+ else Arel::Nodes::HomogeneousIn.new(values, attribute, :in)
29
24
  end
30
25
 
31
26
  unless nils.empty?
32
27
  values_predicate = values_predicate.or(attribute.eq(nil))
33
28
  end
34
29
 
35
- array_predicates = ranges.map { |range| attribute.between(range) }
36
- array_predicates.unshift(values_predicate)
37
- array_predicates.inject { |composite, predicate| composite.or(predicate) }
30
+ if ranges.empty?
31
+ values_predicate
32
+ else
33
+ array_predicates = ranges.map! { |range| predicate_builder.build(attribute, range) }
34
+ array_predicates.inject(values_predicate, &:or)
35
+ end
38
36
  end
39
37
 
40
- module NullPredicate
41
- def self.or(other)
42
- other
38
+ private
39
+ attr_reader :predicate_builder
40
+
41
+ module NullPredicate # :nodoc:
42
+ def self.or(other)
43
+ other
44
+ end
43
45
  end
44
- end
45
46
  end
46
47
  end
47
48
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class PredicateBuilder
5
+ class AssociationQueryValue # :nodoc:
6
+ def initialize(associated_table, value)
7
+ @associated_table = associated_table
8
+ @value = value
9
+ end
10
+
11
+ def queries
12
+ [ associated_table.join_foreign_key => ids ]
13
+ end
14
+
15
+ private
16
+ attr_reader :associated_table, :value
17
+
18
+ def ids
19
+ case value
20
+ when Relation
21
+ value.select_values.empty? ? value.select(primary_key) : value
22
+ when Array
23
+ value.map { |v| convert_to_id(v) }
24
+ else
25
+ convert_to_id(value)
26
+ end
27
+ end
28
+
29
+ def primary_key
30
+ associated_table.join_primary_key
31
+ end
32
+
33
+ def convert_to_id(value)
34
+ if value.respond_to?(primary_key)
35
+ value.public_send(primary_key)
36
+ else
37
+ value
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class PredicateBuilder
5
+ class BasicObjectHandler # :nodoc:
6
+ def initialize(predicate_builder)
7
+ @predicate_builder = predicate_builder
8
+ end
9
+
10
+ def call(attribute, value)
11
+ bind = predicate_builder.build_bind_attribute(attribute.name, value)
12
+ attribute.eq(bind)
13
+ end
14
+
15
+ private
16
+ attr_reader :predicate_builder
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class PredicateBuilder
5
+ class PolymorphicArrayValue # :nodoc:
6
+ def initialize(associated_table, values)
7
+ @associated_table = associated_table
8
+ @values = values
9
+ end
10
+
11
+ def queries
12
+ return [ associated_table.join_foreign_key => values ] if values.empty?
13
+
14
+ type_to_ids_mapping.map do |type, ids|
15
+ query = {}
16
+ query[associated_table.join_foreign_type] = type if type
17
+ query[associated_table.join_foreign_key] = ids
18
+ query
19
+ end
20
+ end
21
+
22
+ private
23
+ attr_reader :associated_table, :values
24
+
25
+ def type_to_ids_mapping
26
+ default_hash = Hash.new { |hsh, key| hsh[key] = [] }
27
+ values.each_with_object(default_hash) do |value, hash|
28
+ hash[klass(value)&.polymorphic_name] << convert_to_id(value)
29
+ end
30
+ end
31
+
32
+ def primary_key(value)
33
+ associated_table.join_primary_key(klass(value))
34
+ end
35
+
36
+ def klass(value)
37
+ case value
38
+ when Base
39
+ value.class
40
+ when Relation
41
+ value.klass
42
+ end
43
+ end
44
+
45
+ def convert_to_id(value)
46
+ case value
47
+ when Base
48
+ value._read_attribute(primary_key(value))
49
+ when Relation
50
+ value.select(primary_key(value))
51
+ else
52
+ value
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class PredicateBuilder
5
+ class RangeHandler # :nodoc:
6
+ RangeWithBinds = Struct.new(:begin, :end, :exclude_end?)
7
+
8
+ def initialize(predicate_builder)
9
+ @predicate_builder = predicate_builder
10
+ end
11
+
12
+ def call(attribute, value)
13
+ begin_bind = predicate_builder.build_bind_attribute(attribute.name, value.begin)
14
+ end_bind = predicate_builder.build_bind_attribute(attribute.name, value.end)
15
+ attribute.between(RangeWithBinds.new(begin_bind, end_bind, value.exclude_end?))
16
+ end
17
+
18
+ private
19
+ attr_reader :predicate_builder
20
+ end
21
+ end
22
+ end
@@ -1,9 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  class PredicateBuilder
3
5
  class RelationHandler # :nodoc:
4
6
  def call(attribute, value)
7
+ if value.eager_loading?
8
+ value = value.send(:apply_join_dependency)
9
+ end
10
+
5
11
  if value.select_values.empty?
6
- value = value.select(value.klass.arel_table[value.klass.primary_key])
12
+ value = value.select(value.table[value.klass.primary_key])
7
13
  end
8
14
 
9
15
  attribute.in(value.arel)