activerecord 5.0.7.2 → 6.1.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 (363) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +829 -2015
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +11 -9
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record.rb +37 -29
  8. data/lib/active_record/aggregations.rb +249 -247
  9. data/lib/active_record/association_relation.rb +30 -18
  10. data/lib/active_record/associations.rb +1714 -1596
  11. data/lib/active_record/associations/alias_tracker.rb +36 -42
  12. data/lib/active_record/associations/association.rb +143 -68
  13. data/lib/active_record/associations/association_scope.rb +98 -94
  14. data/lib/active_record/associations/belongs_to_association.rb +76 -46
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
  16. data/lib/active_record/associations/builder/association.rb +27 -28
  17. data/lib/active_record/associations/builder/belongs_to.rb +52 -60
  18. data/lib/active_record/associations/builder/collection_association.rb +12 -22
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +40 -62
  20. data/lib/active_record/associations/builder/has_many.rb +10 -2
  21. data/lib/active_record/associations/builder/has_one.rb +35 -2
  22. data/lib/active_record/associations/builder/singular_association.rb +5 -1
  23. data/lib/active_record/associations/collection_association.rb +104 -259
  24. data/lib/active_record/associations/collection_proxy.rb +169 -125
  25. data/lib/active_record/associations/foreign_association.rb +22 -0
  26. data/lib/active_record/associations/has_many_association.rb +46 -31
  27. data/lib/active_record/associations/has_many_through_association.rb +66 -46
  28. data/lib/active_record/associations/has_one_association.rb +71 -52
  29. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  30. data/lib/active_record/associations/join_dependency.rb +169 -180
  31. data/lib/active_record/associations/join_dependency/join_association.rb +53 -79
  32. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  33. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  34. data/lib/active_record/associations/preloader.rb +97 -104
  35. data/lib/active_record/associations/preloader/association.rb +109 -97
  36. data/lib/active_record/associations/preloader/through_association.rb +77 -76
  37. data/lib/active_record/associations/singular_association.rb +12 -45
  38. data/lib/active_record/associations/through_association.rb +27 -15
  39. data/lib/active_record/attribute_assignment.rb +55 -60
  40. data/lib/active_record/attribute_methods.rb +111 -141
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +17 -9
  42. data/lib/active_record/attribute_methods/dirty.rb +172 -112
  43. data/lib/active_record/attribute_methods/primary_key.rb +88 -91
  44. data/lib/active_record/attribute_methods/query.rb +6 -8
  45. data/lib/active_record/attribute_methods/read.rb +18 -50
  46. data/lib/active_record/attribute_methods/serialization.rb +38 -10
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +38 -66
  48. data/lib/active_record/attribute_methods/write.rb +25 -32
  49. data/lib/active_record/attributes.rb +69 -31
  50. data/lib/active_record/autosave_association.rb +102 -66
  51. data/lib/active_record/base.rb +16 -25
  52. data/lib/active_record/callbacks.rb +202 -43
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +11 -12
  55. data/lib/active_record/connection_adapters.rb +50 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +661 -375
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +14 -38
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +269 -105
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +54 -35
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +137 -93
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +155 -113
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +328 -162
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +591 -259
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +229 -91
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +392 -244
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +457 -582
  69. data/lib/active_record/connection_adapters/column.rb +55 -13
  70. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  71. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +135 -49
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +79 -49
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +66 -56
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +20 -12
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +74 -37
  82. data/lib/active_record/connection_adapters/pool_config.rb +63 -0
  83. data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
  84. data/lib/active_record/connection_adapters/postgresql/column.rb +39 -28
  85. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +70 -101
  86. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  87. data/lib/active_record/connection_adapters/postgresql/oid.rb +26 -21
  88. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  90. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -6
  93. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -4
  95. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  96. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  97. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -18
  98. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  101. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  104. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +30 -9
  106. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -30
  107. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  108. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  109. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
  110. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  111. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  112. data/lib/active_record/connection_adapters/postgresql/quoting.rb +98 -38
  113. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +21 -27
  114. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
  115. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  116. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
  117. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +426 -324
  118. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +32 -23
  119. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
  120. data/lib/active_record/connection_adapters/postgresql_adapter.rb +418 -293
  121. data/lib/active_record/connection_adapters/schema_cache.rb +135 -18
  122. data/lib/active_record/connection_adapters/sql_type_metadata.rb +22 -7
  123. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
  124. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  125. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
  126. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -6
  127. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  128. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  129. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
  130. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +282 -290
  131. data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
  132. data/lib/active_record/connection_handling.rb +287 -45
  133. data/lib/active_record/core.rb +385 -181
  134. data/lib/active_record/counter_cache.rb +60 -28
  135. data/lib/active_record/database_configurations.rb +272 -0
  136. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  137. data/lib/active_record/database_configurations/database_config.rb +80 -0
  138. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  139. data/lib/active_record/database_configurations/url_config.rb +53 -0
  140. data/lib/active_record/delegated_type.rb +209 -0
  141. data/lib/active_record/destroy_association_async_job.rb +36 -0
  142. data/lib/active_record/dynamic_matchers.rb +87 -87
  143. data/lib/active_record/enum.rb +122 -47
  144. data/lib/active_record/errors.rb +153 -22
  145. data/lib/active_record/explain.rb +13 -8
  146. data/lib/active_record/explain_registry.rb +3 -1
  147. data/lib/active_record/explain_subscriber.rb +9 -4
  148. data/lib/active_record/fixture_set/file.rb +20 -22
  149. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  150. data/lib/active_record/fixture_set/render_context.rb +17 -0
  151. data/lib/active_record/fixture_set/table_row.rb +152 -0
  152. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  153. data/lib/active_record/fixtures.rb +246 -507
  154. data/lib/active_record/gem_version.rb +6 -4
  155. data/lib/active_record/inheritance.rb +168 -95
  156. data/lib/active_record/insert_all.rb +208 -0
  157. data/lib/active_record/integration.rb +114 -25
  158. data/lib/active_record/internal_metadata.rb +30 -24
  159. data/lib/active_record/legacy_yaml_adapter.rb +11 -5
  160. data/lib/active_record/locking/optimistic.rb +81 -85
  161. data/lib/active_record/locking/pessimistic.rb +22 -6
  162. data/lib/active_record/log_subscriber.rb +68 -31
  163. data/lib/active_record/middleware/database_selector.rb +77 -0
  164. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  165. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  166. data/lib/active_record/migration.rb +439 -342
  167. data/lib/active_record/migration/command_recorder.rb +152 -98
  168. data/lib/active_record/migration/compatibility.rb +229 -60
  169. data/lib/active_record/migration/join_table.rb +8 -7
  170. data/lib/active_record/model_schema.rb +230 -122
  171. data/lib/active_record/nested_attributes.rb +213 -203
  172. data/lib/active_record/no_touching.rb +11 -2
  173. data/lib/active_record/null_relation.rb +12 -34
  174. data/lib/active_record/persistence.rb +471 -97
  175. data/lib/active_record/query_cache.rb +23 -12
  176. data/lib/active_record/querying.rb +43 -25
  177. data/lib/active_record/railtie.rb +155 -43
  178. data/lib/active_record/railties/console_sandbox.rb +2 -0
  179. data/lib/active_record/railties/controller_runtime.rb +34 -33
  180. data/lib/active_record/railties/databases.rake +507 -195
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +245 -269
  183. data/lib/active_record/relation.rb +475 -324
  184. data/lib/active_record/relation/batches.rb +125 -72
  185. data/lib/active_record/relation/batches/batch_enumerator.rb +28 -10
  186. data/lib/active_record/relation/calculations.rb +267 -171
  187. data/lib/active_record/relation/delegation.rb +73 -69
  188. data/lib/active_record/relation/finder_methods.rb +238 -248
  189. data/lib/active_record/relation/from_clause.rb +7 -9
  190. data/lib/active_record/relation/merger.rb +95 -77
  191. data/lib/active_record/relation/predicate_builder.rb +109 -110
  192. data/lib/active_record/relation/predicate_builder/array_handler.rb +22 -17
  193. data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
  194. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  195. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +55 -0
  196. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  197. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  198. data/lib/active_record/relation/query_attribute.rb +33 -2
  199. data/lib/active_record/relation/query_methods.rb +654 -374
  200. data/lib/active_record/relation/record_fetch_warning.rb +8 -6
  201. data/lib/active_record/relation/spawn_methods.rb +15 -14
  202. data/lib/active_record/relation/where_clause.rb +171 -109
  203. data/lib/active_record/result.rb +88 -51
  204. data/lib/active_record/runtime_registry.rb +5 -3
  205. data/lib/active_record/sanitization.rb +73 -100
  206. data/lib/active_record/schema.rb +7 -14
  207. data/lib/active_record/schema_dumper.rb +101 -69
  208. data/lib/active_record/schema_migration.rb +16 -12
  209. data/lib/active_record/scoping.rb +20 -20
  210. data/lib/active_record/scoping/default.rb +92 -95
  211. data/lib/active_record/scoping/named.rb +39 -30
  212. data/lib/active_record/secure_token.rb +19 -9
  213. data/lib/active_record/serialization.rb +7 -3
  214. data/lib/active_record/signed_id.rb +116 -0
  215. data/lib/active_record/statement_cache.rb +80 -29
  216. data/lib/active_record/store.rb +122 -42
  217. data/lib/active_record/suppressor.rb +6 -3
  218. data/lib/active_record/table_metadata.rb +51 -39
  219. data/lib/active_record/tasks/database_tasks.rb +332 -115
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +66 -104
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +84 -56
  222. data/lib/active_record/tasks/sqlite_database_tasks.rb +40 -19
  223. data/lib/active_record/test_databases.rb +24 -0
  224. data/lib/active_record/test_fixtures.rb +246 -0
  225. data/lib/active_record/timestamp.rb +70 -38
  226. data/lib/active_record/touch_later.rb +26 -24
  227. data/lib/active_record/transactions.rb +121 -184
  228. data/lib/active_record/translation.rb +3 -1
  229. data/lib/active_record/type.rb +29 -17
  230. data/lib/active_record/type/adapter_specific_registry.rb +44 -48
  231. data/lib/active_record/type/date.rb +2 -0
  232. data/lib/active_record/type/date_time.rb +2 -0
  233. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  234. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  235. data/lib/active_record/type/internal/timezone.rb +2 -0
  236. data/lib/active_record/type/json.rb +30 -0
  237. data/lib/active_record/type/serialized.rb +20 -9
  238. data/lib/active_record/type/text.rb +11 -0
  239. data/lib/active_record/type/time.rb +12 -1
  240. data/lib/active_record/type/type_map.rb +14 -17
  241. data/lib/active_record/type/unsigned_integer.rb +16 -0
  242. data/lib/active_record/type_caster.rb +4 -2
  243. data/lib/active_record/type_caster/connection.rb +17 -13
  244. data/lib/active_record/type_caster/map.rb +10 -6
  245. data/lib/active_record/validations.rb +8 -5
  246. data/lib/active_record/validations/absence.rb +2 -0
  247. data/lib/active_record/validations/associated.rb +4 -3
  248. data/lib/active_record/validations/length.rb +2 -0
  249. data/lib/active_record/validations/numericality.rb +35 -0
  250. data/lib/active_record/validations/presence.rb +4 -2
  251. data/lib/active_record/validations/uniqueness.rb +52 -45
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/arel.rb +54 -0
  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.rb +70 -0
  269. data/lib/arel/nodes/and.rb +32 -0
  270. data/lib/arel/nodes/ascending.rb +23 -0
  271. data/lib/arel/nodes/binary.rb +126 -0
  272. data/lib/arel/nodes/bind_param.rb +44 -0
  273. data/lib/arel/nodes/case.rb +55 -0
  274. data/lib/arel/nodes/casted.rb +62 -0
  275. data/lib/arel/nodes/comment.rb +29 -0
  276. data/lib/arel/nodes/count.rb +12 -0
  277. data/lib/arel/nodes/delete_statement.rb +45 -0
  278. data/lib/arel/nodes/descending.rb +23 -0
  279. data/lib/arel/nodes/equality.rb +15 -0
  280. data/lib/arel/nodes/extract.rb +24 -0
  281. data/lib/arel/nodes/false.rb +16 -0
  282. data/lib/arel/nodes/full_outer_join.rb +8 -0
  283. data/lib/arel/nodes/function.rb +44 -0
  284. data/lib/arel/nodes/grouping.rb +11 -0
  285. data/lib/arel/nodes/homogeneous_in.rb +72 -0
  286. data/lib/arel/nodes/in.rb +15 -0
  287. data/lib/arel/nodes/infix_operation.rb +92 -0
  288. data/lib/arel/nodes/inner_join.rb +8 -0
  289. data/lib/arel/nodes/insert_statement.rb +37 -0
  290. data/lib/arel/nodes/join_source.rb +20 -0
  291. data/lib/arel/nodes/matches.rb +18 -0
  292. data/lib/arel/nodes/named_function.rb +23 -0
  293. data/lib/arel/nodes/node.rb +51 -0
  294. data/lib/arel/nodes/node_expression.rb +13 -0
  295. data/lib/arel/nodes/ordering.rb +27 -0
  296. data/lib/arel/nodes/outer_join.rb +8 -0
  297. data/lib/arel/nodes/over.rb +15 -0
  298. data/lib/arel/nodes/regexp.rb +16 -0
  299. data/lib/arel/nodes/right_outer_join.rb +8 -0
  300. data/lib/arel/nodes/select_core.rb +67 -0
  301. data/lib/arel/nodes/select_statement.rb +41 -0
  302. data/lib/arel/nodes/sql_literal.rb +19 -0
  303. data/lib/arel/nodes/string_join.rb +11 -0
  304. data/lib/arel/nodes/table_alias.rb +31 -0
  305. data/lib/arel/nodes/terminal.rb +16 -0
  306. data/lib/arel/nodes/true.rb +16 -0
  307. data/lib/arel/nodes/unary.rb +44 -0
  308. data/lib/arel/nodes/unary_operation.rb +20 -0
  309. data/lib/arel/nodes/unqualified_column.rb +22 -0
  310. data/lib/arel/nodes/update_statement.rb +41 -0
  311. data/lib/arel/nodes/values_list.rb +9 -0
  312. data/lib/arel/nodes/window.rb +126 -0
  313. data/lib/arel/nodes/with.rb +11 -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.rb +13 -0
  321. data/lib/arel/visitors/dot.rb +308 -0
  322. data/lib/arel/visitors/mysql.rb +93 -0
  323. data/lib/arel/visitors/postgresql.rb +120 -0
  324. data/lib/arel/visitors/sqlite.rb +38 -0
  325. data/lib/arel/visitors/to_sql.rb +899 -0
  326. data/lib/arel/visitors/visitor.rb +45 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/rails/generators/active_record.rb +7 -5
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  330. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  331. data/lib/rails/generators/active_record/migration.rb +22 -3
  332. data/lib/rails/generators/active_record/migration/migration_generator.rb +38 -35
  333. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +3 -1
  334. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +7 -5
  335. data/lib/rails/generators/active_record/model/model_generator.rb +41 -25
  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 → model.rb.tt} +10 -1
  338. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  339. metadata +141 -57
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  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 -15
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  347. data/lib/active_record/attribute.rb +0 -213
  348. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  349. data/lib/active_record/attribute_decorators.rb +0 -67
  350. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  351. data/lib/active_record/attribute_set.rb +0 -110
  352. data/lib/active_record/attribute_set/builder.rb +0 -132
  353. data/lib/active_record/collection_cache_key.rb +0 -50
  354. data/lib/active_record/connection_adapters/connection_specification.rb +0 -263
  355. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -22
  356. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  357. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  358. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  359. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -17
  360. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  361. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  362. data/lib/active_record/relation/where_clause_factory.rb +0 -38
  363. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Associations
3
5
  class AssociationScope #:nodoc:
4
- def self.scope(association, connection)
5
- INSTANCE.scope(association, connection)
6
+ def self.scope(association)
7
+ INSTANCE.scope(association)
6
8
  end
7
9
 
8
10
  def self.create(&block)
@@ -16,20 +18,17 @@ module ActiveRecord
16
18
 
17
19
  INSTANCE = create
18
20
 
19
- def scope(association, connection)
21
+ def scope(association)
20
22
  klass = association.klass
21
23
  reflection = association.reflection
22
24
  scope = klass.unscoped
23
25
  owner = association.owner
24
- alias_tracker = AliasTracker.create connection, association.klass.table_name, klass.type_caster
25
- chain_head, chain_tail = get_chain(reflection, association, alias_tracker)
26
+ chain = get_chain(reflection, association, scope.alias_tracker)
26
27
 
27
28
  scope.extending! reflection.extensions
28
- add_constraints(scope, owner, klass, reflection, chain_head, chain_tail)
29
- end
30
-
31
- def join_type
32
- Arel::Nodes::InnerJoin
29
+ scope = add_constraints(scope, owner, chain)
30
+ scope.limit!(1) unless reflection.collection?
31
+ scope
33
32
  end
34
33
 
35
34
  def self.get_bind_values(owner, chain)
@@ -38,129 +37,134 @@ module ActiveRecord
38
37
 
39
38
  binds << last_reflection.join_id_for(owner)
40
39
  if last_reflection.type
41
- binds << owner.class.base_class.name
40
+ binds << owner.class.polymorphic_name
42
41
  end
43
42
 
44
43
  chain.each_cons(2).each do |reflection, next_reflection|
45
44
  if reflection.type
46
- binds << next_reflection.klass.base_class.name
45
+ binds << next_reflection.klass.polymorphic_name
47
46
  end
48
47
  end
49
48
  binds
50
49
  end
51
50
 
52
- protected
51
+ private
52
+ attr_reader :value_transformation
53
53
 
54
- attr_reader :value_transformation
54
+ def join(table, constraint)
55
+ Arel::Nodes::LeadingJoin.new(table, Arel::Nodes::On.new(constraint))
56
+ end
55
57
 
56
- private
57
- def join(table, constraint)
58
- table.create_join(table, table.create_on(constraint), join_type)
59
- end
58
+ def last_chain_scope(scope, reflection, owner)
59
+ primary_key = reflection.join_primary_key
60
+ foreign_key = reflection.join_foreign_key
60
61
 
61
- def last_chain_scope(scope, table, reflection, owner, association_klass)
62
- join_keys = reflection.join_keys(association_klass)
63
- key = join_keys.key
64
- foreign_key = join_keys.foreign_key
62
+ table = reflection.aliased_table
63
+ value = transform_value(owner[foreign_key])
64
+ scope = apply_scope(scope, table, primary_key, value)
65
65
 
66
- value = transform_value(owner[foreign_key])
67
- scope = scope.where(table.name => { key => value })
66
+ if reflection.type
67
+ polymorphic_type = transform_value(owner.class.polymorphic_name)
68
+ scope = apply_scope(scope, table, reflection.type, polymorphic_type)
69
+ end
68
70
 
69
- if reflection.type
70
- polymorphic_type = transform_value(owner.class.base_class.name)
71
- scope = scope.where(table.name => { reflection.type => polymorphic_type })
71
+ scope
72
72
  end
73
73
 
74
- scope
75
- end
74
+ def transform_value(value)
75
+ value_transformation.call(value)
76
+ end
76
77
 
77
- def transform_value(value)
78
- value_transformation.call(value)
79
- end
78
+ def next_chain_scope(scope, reflection, next_reflection)
79
+ primary_key = reflection.join_primary_key
80
+ foreign_key = reflection.join_foreign_key
80
81
 
81
- def next_chain_scope(scope, table, reflection, association_klass, foreign_table, next_reflection)
82
- join_keys = reflection.join_keys(association_klass)
83
- key = join_keys.key
84
- foreign_key = join_keys.foreign_key
82
+ table = reflection.aliased_table
83
+ foreign_table = next_reflection.aliased_table
84
+ constraint = table[primary_key].eq(foreign_table[foreign_key])
85
85
 
86
- constraint = table[key].eq(foreign_table[foreign_key])
86
+ if reflection.type
87
+ value = transform_value(next_reflection.klass.polymorphic_name)
88
+ scope = apply_scope(scope, table, reflection.type, value)
89
+ end
87
90
 
88
- if reflection.type
89
- value = transform_value(next_reflection.klass.base_class.name)
90
- scope = scope.where(table.name => { reflection.type => value })
91
+ scope.joins!(join(foreign_table, constraint))
91
92
  end
92
93
 
93
- scope = scope.joins(join(foreign_table, constraint))
94
- end
94
+ class ReflectionProxy < SimpleDelegator # :nodoc:
95
+ attr_reader :aliased_table
95
96
 
96
- class ReflectionProxy < SimpleDelegator # :nodoc:
97
- attr_accessor :next
98
- attr_reader :alias_name
97
+ def initialize(reflection, aliased_table)
98
+ super(reflection)
99
+ @aliased_table = aliased_table
100
+ end
99
101
 
100
- def initialize(reflection, alias_name)
101
- super(reflection)
102
- @alias_name = alias_name
102
+ def all_includes; nil; end
103
103
  end
104
104
 
105
- def all_includes; nil; end
106
- end
107
-
108
- def get_chain(reflection, association, tracker)
109
- name = reflection.name
110
- runtime_reflection = Reflection::RuntimeReflection.new(reflection, association)
111
- previous_reflection = runtime_reflection
112
- reflection.chain.drop(1).each do |refl|
113
- alias_name = tracker.aliased_table_for(refl.table_name, refl.alias_candidate(name))
114
- proxy = ReflectionProxy.new(refl, alias_name)
115
- previous_reflection.next = proxy
116
- previous_reflection = proxy
105
+ def get_chain(reflection, association, tracker)
106
+ name = reflection.name
107
+ chain = [Reflection::RuntimeReflection.new(reflection, association)]
108
+ reflection.chain.drop(1).each do |refl|
109
+ aliased_table = tracker.aliased_table_for(refl.klass.arel_table) do
110
+ refl.alias_candidate(name)
111
+ end
112
+ chain << ReflectionProxy.new(refl, aliased_table)
113
+ end
114
+ chain
117
115
  end
118
- [runtime_reflection, previous_reflection]
119
- end
120
116
 
121
- def add_constraints(scope, owner, association_klass, refl, chain_head, chain_tail)
122
- owner_reflection = chain_tail
123
- table = owner_reflection.alias_name
124
- scope = last_chain_scope(scope, table, owner_reflection, owner, association_klass)
117
+ def add_constraints(scope, owner, chain)
118
+ scope = last_chain_scope(scope, chain.last, owner)
125
119
 
126
- reflection = chain_head
127
- loop do
128
- break unless reflection
129
- table = reflection.alias_name
130
-
131
- unless reflection == chain_tail
132
- next_reflection = reflection.next
133
- foreign_table = next_reflection.alias_name
134
- scope = next_chain_scope(scope, table, reflection, association_klass, foreign_table, next_reflection)
120
+ chain.each_cons(2) do |reflection, next_reflection|
121
+ scope = next_chain_scope(scope, reflection, next_reflection)
135
122
  end
136
123
 
137
- # Exclude the scope of the association itself, because that
138
- # was already merged in the #scope method.
139
- reflection.constraints.each do |scope_chain_item|
140
- item = eval_scope(reflection.klass, scope_chain_item, owner)
124
+ chain_head = chain.first
125
+ chain.reverse_each do |reflection|
126
+ # Exclude the scope of the association itself, because that
127
+ # was already merged in the #scope method.
128
+ reflection.constraints.each do |scope_chain_item|
129
+ item = eval_scope(reflection, scope_chain_item, owner)
141
130
 
142
- if scope_chain_item == refl.scope
143
- scope.merge! item.except(:where, :includes)
144
- end
131
+ if scope_chain_item == chain_head.scope
132
+ scope.merge! item.except(:where, :includes, :unscope, :order)
133
+ elsif !item.references_values.empty?
134
+ scope.merge! item.only(:joins, :left_outer_joins)
145
135
 
146
- reflection.all_includes do
147
- scope.includes! item.includes_values
148
- end
136
+ associations = item.eager_load_values | item.includes_values
137
+
138
+ unless associations.empty?
139
+ scope.joins! item.construct_join_dependency(associations, Arel::Nodes::OuterJoin)
140
+ end
141
+ end
149
142
 
150
- scope.unscope!(*item.unscope_values)
151
- scope.where_clause += item.where_clause
152
- scope.order_values |= item.order_values
143
+ reflection.all_includes do
144
+ scope.includes_values |= item.includes_values
145
+ end
146
+
147
+ scope.unscope!(*item.unscope_values)
148
+ scope.where_clause += item.where_clause
149
+ scope.order_values = item.order_values | scope.order_values
150
+ end
153
151
  end
154
152
 
155
- reflection = reflection.next
153
+ scope
156
154
  end
157
155
 
158
- scope
159
- end
156
+ def apply_scope(scope, table, key, value)
157
+ if scope.table == table
158
+ scope.where!(key => value)
159
+ else
160
+ scope.where!(table.name => { key => value })
161
+ end
162
+ end
160
163
 
161
- def eval_scope(klass, scope, owner)
162
- klass.unscoped.instance_exec(owner, &scope)
163
- end
164
+ def eval_scope(reflection, scope, owner)
165
+ relation = reflection.build_scope(reflection.aliased_table)
166
+ relation.instance_exec(owner, &scope) || relation
167
+ end
164
168
  end
165
169
  end
166
170
  end
@@ -1,25 +1,40 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
- # = Active Record Belongs To Association
3
4
  module Associations
5
+ # = Active Record Belongs To Association
4
6
  class BelongsToAssociation < SingularAssociation #:nodoc:
5
-
6
7
  def handle_dependency
7
- target.send(options[:dependent]) if load_target
8
- end
9
-
10
- def replace(record)
11
- if record
12
- raise_on_type_mismatch!(record)
13
- update_counters_on_replace(record)
14
- replace_keys(record)
15
- set_inverse_instance(record)
16
- @updated = true
8
+ return unless load_target
9
+
10
+ case options[:dependent]
11
+ when :destroy
12
+ target.destroy
13
+ raise ActiveRecord::Rollback unless target.destroyed?
14
+ when :destroy_async
15
+ id = owner.public_send(reflection.foreign_key.to_sym)
16
+ primary_key_column = reflection.active_record_primary_key.to_sym
17
+
18
+ enqueue_destroy_association(
19
+ owner_model_name: owner.class.to_s,
20
+ owner_id: owner.id,
21
+ association_class: reflection.klass.to_s,
22
+ association_ids: [id],
23
+ association_primary_key_column: primary_key_column,
24
+ ensuring_owner_was_method: options.fetch(:ensuring_owner_was, nil)
25
+ )
17
26
  else
18
- decrement_counters
19
- remove_keys
27
+ target.public_send(options[:dependent])
20
28
  end
29
+ end
30
+
31
+ def inversed_from(record)
32
+ replace_keys(record)
33
+ super
34
+ end
21
35
 
22
- self.target = record
36
+ def default(&block)
37
+ writer(owner.instance_exec(&block)) if reader.nil?
23
38
  end
24
39
 
25
40
  def reset
@@ -31,26 +46,60 @@ module ActiveRecord
31
46
  @updated
32
47
  end
33
48
 
34
- def decrement_counters # :nodoc:
49
+ def decrement_counters
35
50
  update_counters(-1)
36
51
  end
37
52
 
38
- def increment_counters # :nodoc:
53
+ def increment_counters
39
54
  update_counters(1)
40
55
  end
41
56
 
57
+ def decrement_counters_before_last_save
58
+ if reflection.polymorphic?
59
+ model_was = owner.attribute_before_last_save(reflection.foreign_type)&.constantize
60
+ else
61
+ model_was = klass
62
+ end
63
+
64
+ foreign_key_was = owner.attribute_before_last_save(reflection.foreign_key)
65
+
66
+ if foreign_key_was && model_was < ActiveRecord::Base
67
+ update_counters_via_scope(model_was, foreign_key_was, -1)
68
+ end
69
+ end
70
+
71
+ def target_changed?
72
+ owner.saved_change_to_attribute?(reflection.foreign_key)
73
+ end
74
+
42
75
  private
76
+ def replace(record)
77
+ if record
78
+ raise_on_type_mismatch!(record)
79
+ set_inverse_instance(record)
80
+ @updated = true
81
+ end
82
+
83
+ replace_keys(record, force: true)
84
+
85
+ self.target = record
86
+ end
43
87
 
44
88
  def update_counters(by)
45
89
  if require_counter_update? && foreign_key_present?
46
90
  if target && !stale_target?
47
- target.increment!(reflection.counter_cache_column, by)
91
+ target.increment!(reflection.counter_cache_column, by, touch: reflection.options[:touch])
48
92
  else
49
- klass.update_counters(target_id, reflection.counter_cache_column => by)
93
+ update_counters_via_scope(klass, owner._read_attribute(reflection.foreign_key), by)
50
94
  end
51
95
  end
52
96
  end
53
97
 
98
+ def update_counters_via_scope(klass, foreign_key, by)
99
+ scope = klass.unscoped.where!(primary_key(klass) => foreign_key)
100
+ scope.update_counters(reflection.counter_cache_column => by, touch: reflection.options[:touch])
101
+ end
102
+
54
103
  def find_target?
55
104
  !loaded? && foreign_key_present? && klass
56
105
  end
@@ -59,44 +108,25 @@ module ActiveRecord
59
108
  reflection.counter_cache_column && owner.persisted?
60
109
  end
61
110
 
62
- def update_counters_on_replace(record)
63
- if require_counter_update? && different_target?(record)
64
- owner.instance_variable_set :@_after_replace_counter_called, true
65
- record.increment!(reflection.counter_cache_column)
66
- decrement_counters
67
- end
68
- end
69
-
70
- # Checks whether record is different to the current target, without loading it
71
- def different_target?(record)
72
- record.id != owner._read_attribute(reflection.foreign_key)
73
- end
111
+ def replace_keys(record, force: false)
112
+ target_key = record ? record._read_attribute(primary_key(record.class)) : nil
74
113
 
75
- def replace_keys(record)
76
- owner[reflection.foreign_key] = record._read_attribute(reflection.association_primary_key(record.class))
114
+ if force || owner[reflection.foreign_key] != target_key
115
+ owner[reflection.foreign_key] = target_key
116
+ end
77
117
  end
78
118
 
79
- def remove_keys
80
- owner[reflection.foreign_key] = nil
119
+ def primary_key(klass)
120
+ reflection.association_primary_key(klass)
81
121
  end
82
122
 
83
123
  def foreign_key_present?
84
124
  owner._read_attribute(reflection.foreign_key)
85
125
  end
86
126
 
87
- # NOTE - for now, we're only supporting inverse setting from belongs_to back onto
88
- # has_one associations.
89
127
  def invertible_for?(record)
90
128
  inverse = inverse_reflection_for(record)
91
- inverse && inverse.has_one?
92
- end
93
-
94
- def target_id
95
- if options[:primary_key]
96
- owner.send(reflection.name).try(:id)
97
- else
98
- owner._read_attribute(reflection.foreign_key)
99
- end
129
+ inverse && (inverse.has_one? || ActiveRecord::Base.has_many_inversing)
100
130
  end
101
131
 
102
132
  def stale_state
@@ -1,26 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
- # = Active Record Belongs To Polymorphic Association
3
4
  module Associations
5
+ # = Active Record Belongs To Polymorphic Association
4
6
  class BelongsToPolymorphicAssociation < BelongsToAssociation #:nodoc:
5
7
  def klass
6
8
  type = owner[reflection.foreign_type]
7
- type.presence && type.constantize
9
+ type.presence && owner.class.polymorphic_class_for(type)
8
10
  end
9
11
 
10
- private
12
+ def target_changed?
13
+ super || owner.saved_change_to_attribute?(reflection.foreign_type)
14
+ end
11
15
 
12
- def replace_keys(record)
16
+ private
17
+ def replace_keys(record, force: false)
13
18
  super
14
- owner[reflection.foreign_type] = record.class.base_class.name
15
- end
16
19
 
17
- def remove_keys
18
- super
19
- owner[reflection.foreign_type] = nil
20
- end
20
+ target_type = record ? record.class.polymorphic_name : nil
21
21
 
22
- def different_target?(record)
23
- super || record.class != klass
22
+ if force || owner[reflection.foreign_type] != target_type
23
+ owner[reflection.foreign_type] = target_type
24
+ end
24
25
  end
25
26
 
26
27
  def inverse_reflection_for(record)