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,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This is the parent Association class which defines the variables
2
4
  # used by all associations.
3
5
  #
@@ -16,7 +18,9 @@ module ActiveRecord::Associations::Builder # :nodoc:
16
18
  end
17
19
  self.extensions = []
18
20
 
19
- VALID_OPTIONS = [:class_name, :anonymous_class, :foreign_key, :validate] # :nodoc:
21
+ VALID_OPTIONS = [
22
+ :class_name, :anonymous_class, :primary_key, :foreign_key, :dependent, :validate, :inverse_of, :strict_loading
23
+ ].freeze # :nodoc:
20
24
 
21
25
  def self.build(model, name, scope, options, &block)
22
26
  if model.dangerous_attribute_method?(name)
@@ -25,45 +29,32 @@ module ActiveRecord::Associations::Builder # :nodoc:
25
29
  "Please choose a different association name."
26
30
  end
27
31
 
28
- extension = define_extensions model, name, &block
29
- reflection = create_reflection model, name, scope, options, extension
32
+ reflection = create_reflection(model, name, scope, options, &block)
30
33
  define_accessors model, reflection
31
34
  define_callbacks model, reflection
32
35
  define_validations model, reflection
33
36
  reflection
34
37
  end
35
38
 
36
- def self.create_reflection(model, name, scope, options, extension = nil)
39
+ def self.create_reflection(model, name, scope, options, &block)
37
40
  raise ArgumentError, "association names must be a Symbol" unless name.kind_of?(Symbol)
38
41
 
39
- if scope.is_a?(Hash)
40
- options = scope
41
- scope = nil
42
- end
43
-
44
42
  validate_options(options)
45
43
 
46
- scope = build_scope(scope, extension)
44
+ extension = define_extensions(model, name, &block)
45
+ options[:extend] = [*options[:extend], extension] if extension
46
+
47
+ scope = build_scope(scope)
47
48
 
48
49
  ActiveRecord::Reflection.create(macro, name, scope, options, model)
49
50
  end
50
51
 
51
- def self.build_scope(scope, extension)
52
- new_scope = scope
53
-
52
+ def self.build_scope(scope)
54
53
  if scope && scope.arity == 0
55
- new_scope = proc { instance_exec(&scope) }
56
- end
57
-
58
- if extension
59
- new_scope = wrap_scope new_scope, extension
54
+ proc { instance_exec(&scope) }
55
+ else
56
+ scope
60
57
  end
61
-
62
- new_scope
63
- end
64
-
65
- def self.wrap_scope(scope, extension)
66
- scope
67
58
  end
68
59
 
69
60
  def self.macro
@@ -83,7 +74,7 @@ module ActiveRecord::Associations::Builder # :nodoc:
83
74
 
84
75
  def self.define_callbacks(model, reflection)
85
76
  if dependent = reflection.options[:dependent]
86
- check_dependent_options(dependent)
77
+ check_dependent_options(dependent, model)
87
78
  add_destroy_callbacks(model, reflection)
88
79
  end
89
80
 
@@ -107,8 +98,8 @@ module ActiveRecord::Associations::Builder # :nodoc:
107
98
 
108
99
  def self.define_readers(mixin, name)
109
100
  mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
110
- def #{name}(*args)
111
- association(:#{name}).reader(*args)
101
+ def #{name}
102
+ association(:#{name}).reader
112
103
  end
113
104
  CODE
114
105
  end
@@ -129,7 +120,11 @@ module ActiveRecord::Associations::Builder # :nodoc:
129
120
  raise NotImplementedError
130
121
  end
131
122
 
132
- def self.check_dependent_options(dependent)
123
+ def self.check_dependent_options(dependent, model)
124
+ if dependent == :destroy_async && !model.destroy_association_async_job
125
+ err_message = "ActiveJob is required to use destroy_async on associations"
126
+ raise ActiveRecord::ActiveJobRequiredError, err_message
127
+ end
133
128
  unless valid_dependent_options.include? dependent
134
129
  raise ArgumentError, "The :dependent option must be one of #{valid_dependent_options}, but is :#{dependent}"
135
130
  end
@@ -139,5 +134,9 @@ module ActiveRecord::Associations::Builder # :nodoc:
139
134
  name = reflection.name
140
135
  model.before_destroy lambda { |o| o.association(name).handle_dependency }
141
136
  end
137
+
138
+ private_class_method :build_scope, :macro, :valid_options, :validate_options, :define_extensions,
139
+ :define_callbacks, :define_accessors, :define_readers, :define_writers, :define_validations,
140
+ :valid_dependent_options, :check_dependent_options, :add_destroy_callbacks
142
141
  end
143
142
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord::Associations::Builder # :nodoc:
2
4
  class BelongsTo < SingularAssociation #:nodoc:
3
5
  def self.macro
@@ -5,115 +7,102 @@ module ActiveRecord::Associations::Builder # :nodoc:
5
7
  end
6
8
 
7
9
  def self.valid_options(options)
8
- super + [:polymorphic, :touch, :counter_cache, :optional]
10
+ valid = super + [:polymorphic, :counter_cache, :optional, :default]
11
+ valid += [:foreign_type] if options[:polymorphic]
12
+ valid += [:ensuring_owner_was] if options[:dependent] == :destroy_async
13
+ valid
9
14
  end
10
15
 
11
16
  def self.valid_dependent_options
12
- [:destroy, :delete]
17
+ [:destroy, :delete, :destroy_async]
13
18
  end
14
19
 
15
20
  def self.define_callbacks(model, reflection)
16
21
  super
17
22
  add_counter_cache_callbacks(model, reflection) if reflection.options[:counter_cache]
18
23
  add_touch_callbacks(model, reflection) if reflection.options[:touch]
19
- end
20
-
21
- def self.define_accessors(mixin, reflection)
22
- super
23
- add_counter_cache_methods mixin
24
- end
25
-
26
- def self.add_counter_cache_methods(mixin)
27
- return if mixin.method_defined? :belongs_to_counter_cache_after_update
28
-
29
- mixin.class_eval do
30
- def belongs_to_counter_cache_after_update(reflection)
31
- foreign_key = reflection.foreign_key
32
- cache_column = reflection.counter_cache_column
33
-
34
- if (@_after_create_counter_called ||= false)
35
- @_after_create_counter_called = false
36
- elsif (@_after_replace_counter_called ||= false)
37
- @_after_replace_counter_called = false
38
- elsif attribute_changed?(foreign_key) && !new_record?
39
- if reflection.polymorphic?
40
- model = attribute(reflection.foreign_type).try(:constantize)
41
- model_was = attribute_was(reflection.foreign_type).try(:constantize)
42
- else
43
- model = reflection.klass
44
- model_was = reflection.klass
45
- end
46
-
47
- foreign_key_was = attribute_was foreign_key
48
- foreign_key = attribute foreign_key
49
-
50
- if foreign_key && model.respond_to?(:increment_counter)
51
- model.increment_counter(cache_column, foreign_key)
52
- end
53
-
54
- if foreign_key_was && model_was.respond_to?(:decrement_counter)
55
- model_was.decrement_counter(cache_column, foreign_key_was)
56
- end
57
- end
58
- end
59
- end
24
+ add_default_callbacks(model, reflection) if reflection.options[:default]
60
25
  end
61
26
 
62
27
  def self.add_counter_cache_callbacks(model, reflection)
63
28
  cache_column = reflection.counter_cache_column
64
29
 
65
30
  model.after_update lambda { |record|
66
- record.belongs_to_counter_cache_after_update(reflection)
31
+ association = association(reflection.name)
32
+
33
+ if association.target_changed?
34
+ association.increment_counters
35
+ association.decrement_counters_before_last_save
36
+ end
67
37
  }
68
38
 
69
39
  klass = reflection.class_name.safe_constantize
70
40
  klass.attr_readonly cache_column if klass && klass.respond_to?(:attr_readonly)
71
41
  end
72
42
 
73
- def self.touch_record(o, foreign_key, name, touch, touch_method) # :nodoc:
74
- old_foreign_id = o.changed_attributes[foreign_key]
43
+ def self.touch_record(o, changes, foreign_key, name, touch, touch_method) # :nodoc:
44
+ old_foreign_id = changes[foreign_key] && changes[foreign_key].first
75
45
 
76
46
  if old_foreign_id
77
47
  association = o.association(name)
78
48
  reflection = association.reflection
79
49
  if reflection.polymorphic?
80
- klass = o.public_send("#{reflection.foreign_type}_was").constantize
50
+ foreign_type = reflection.foreign_type
51
+ klass = changes[foreign_type] && changes[foreign_type].first || o.public_send(foreign_type)
52
+ klass = klass.constantize
81
53
  else
82
54
  klass = association.klass
83
55
  end
84
- old_record = klass.find_by(klass.primary_key => old_foreign_id)
56
+ primary_key = reflection.association_primary_key(klass)
57
+ old_record = klass.find_by(primary_key => old_foreign_id)
85
58
 
86
59
  if old_record
87
60
  if touch != true
88
- old_record.send(touch_method, touch)
61
+ old_record.public_send(touch_method, touch)
89
62
  else
90
- old_record.send(touch_method)
63
+ old_record.public_send(touch_method)
91
64
  end
92
65
  end
93
66
  end
94
67
 
95
- record = o.send name
68
+ record = o.public_send name
96
69
  if record && record.persisted?
97
70
  if touch != true
98
- record.send(touch_method, touch)
71
+ record.public_send(touch_method, touch)
99
72
  else
100
- record.send(touch_method)
73
+ record.public_send(touch_method)
101
74
  end
102
75
  end
103
76
  end
104
77
 
105
78
  def self.add_touch_callbacks(model, reflection)
106
79
  foreign_key = reflection.foreign_key
107
- n = reflection.name
80
+ name = reflection.name
108
81
  touch = reflection.options[:touch]
109
82
 
110
- callback = lambda { |record|
111
- BelongsTo.touch_record(record, foreign_key, n, touch, belongs_to_touch_method)
112
- }
83
+ callback = lambda { |changes_method| lambda { |record|
84
+ BelongsTo.touch_record(record, record.send(changes_method), foreign_key, name, touch, belongs_to_touch_method)
85
+ }}
86
+
87
+ if reflection.counter_cache_column
88
+ touch_callback = callback.(:saved_changes)
89
+ update_callback = lambda { |record|
90
+ instance_exec(record, &touch_callback) unless association(reflection.name).target_changed?
91
+ }
92
+ model.after_update update_callback, if: :saved_changes?
93
+ else
94
+ model.after_create callback.(:saved_changes), if: :saved_changes?
95
+ model.after_update callback.(:saved_changes), if: :saved_changes?
96
+ model.after_destroy callback.(:changes_to_save)
97
+ end
113
98
 
114
- model.after_save callback, if: :changed?
115
- model.after_touch callback
116
- model.after_destroy callback
99
+ model.after_touch callback.(:changes_to_save)
100
+ end
101
+
102
+ def self.add_default_callbacks(model, reflection)
103
+ model.before_validation lambda { |o|
104
+ o.association(reflection.name).default(&reflection.options[:default])
105
+ }
117
106
  end
118
107
 
119
108
  def self.add_destroy_callbacks(model, reflection)
@@ -137,5 +126,8 @@ module ActiveRecord::Associations::Builder # :nodoc:
137
126
  model.validates_presence_of reflection.name, message: :required
138
127
  end
139
128
  end
129
+
130
+ private_class_method :macro, :valid_options, :valid_dependent_options, :define_callbacks, :define_validations,
131
+ :add_counter_cache_callbacks, :add_touch_callbacks, :add_default_callbacks, :add_destroy_callbacks
140
132
  end
141
133
  end
@@ -1,15 +1,13 @@
1
- # This class is inherited by the has_many and has_many_and_belongs_to_many association classes
1
+ # frozen_string_literal: true
2
2
 
3
- require 'active_record/associations'
3
+ require "active_record/associations"
4
4
 
5
5
  module ActiveRecord::Associations::Builder # :nodoc:
6
6
  class CollectionAssociation < Association #:nodoc:
7
-
8
7
  CALLBACKS = [:before_add, :after_add, :before_remove, :after_remove]
9
8
 
10
9
  def self.valid_options(options)
11
- super + [:table_name, :before_add,
12
- :after_add, :before_remove, :after_remove, :extend]
10
+ super + [:before_add, :after_add, :before_remove, :after_remove, :extend]
13
11
  end
14
12
 
15
13
  def self.define_callbacks(model, reflection)
@@ -21,19 +19,21 @@ module ActiveRecord::Associations::Builder # :nodoc:
21
19
  }
22
20
  end
23
21
 
24
- def self.define_extensions(model, name)
22
+ def self.define_extensions(model, name, &block)
25
23
  if block_given?
26
- extension_module_name = "#{model.name.demodulize}#{name.to_s.camelize}AssociationExtension"
27
- extension = Module.new(&Proc.new)
28
- model.parent.const_set(extension_module_name, extension)
24
+ extension_module_name = "#{name.to_s.camelize}AssociationExtension"
25
+ extension = Module.new(&block)
26
+ model.const_set(extension_module_name, extension)
29
27
  end
30
28
  end
31
29
 
32
30
  def self.define_callback(model, callback_name, name, options)
33
31
  full_callback_name = "#{callback_name}_for_#{name}"
34
32
 
35
- # TODO : why do i need method_defined? I think its because of the inheritance chain
36
- model.class_attribute full_callback_name unless model.method_defined?(full_callback_name)
33
+ unless model.method_defined?(full_callback_name)
34
+ model.class_attribute(full_callback_name, instance_accessor: false, instance_predicate: false)
35
+ end
36
+
37
37
  callbacks = Array(options[callback_name.to_sym]).map do |callback|
38
38
  case callback
39
39
  when Symbol
@@ -68,16 +68,6 @@ module ActiveRecord::Associations::Builder # :nodoc:
68
68
  CODE
69
69
  end
70
70
 
71
- def self.wrap_scope(scope, mod)
72
- if scope
73
- if scope.arity > 0
74
- proc { |owner| instance_exec(owner, &scope).extending(mod) }
75
- else
76
- proc { instance_exec(&scope).extending(mod) }
77
- end
78
- else
79
- proc { extending(mod) }
80
- end
81
- end
71
+ private_class_method :valid_options, :define_callback, :define_extensions, :define_readers, :define_writers
82
72
  end
83
73
  end
@@ -1,38 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord::Associations::Builder # :nodoc:
2
4
  class HasAndBelongsToMany # :nodoc:
3
- class JoinTableResolver # :nodoc:
4
- KnownTable = Struct.new :join_table
5
-
6
- class KnownClass # :nodoc:
7
- def initialize(lhs_class, rhs_class_name)
8
- @lhs_class = lhs_class
9
- @rhs_class_name = rhs_class_name
10
- @join_table = nil
11
- end
12
-
13
- def join_table
14
- @join_table ||= [@lhs_class.table_name, klass.table_name].sort.join("\0").gsub(/^(.*[._])(.+)\0\1(.+)/, '\1\2_\3').tr("\0", "_")
15
- end
16
-
17
- private
18
-
19
- def klass
20
- @lhs_class.send(:compute_type, @rhs_class_name)
21
- end
22
- end
23
-
24
- def self.build(lhs_class, name, options)
25
- if options[:join_table]
26
- KnownTable.new options[:join_table].to_s
27
- else
28
- class_name = options.fetch(:class_name) {
29
- name.to_s.camelize.singularize
30
- }
31
- KnownClass.new lhs_class, class_name
32
- end
33
- end
34
- end
35
-
36
5
  attr_reader :lhs_model, :association_name, :options
37
6
 
38
7
  def initialize(association_name, lhs_model, options)
@@ -42,10 +11,8 @@ module ActiveRecord::Associations::Builder # :nodoc:
42
11
  end
43
12
 
44
13
  def through_model
45
- habtm = JoinTableResolver.build lhs_model, association_name, options
46
-
47
14
  join_model = Class.new(ActiveRecord::Base) {
48
- class << self;
15
+ class << self
49
16
  attr_accessor :left_model
50
17
  attr_accessor :name
51
18
  attr_accessor :table_name_resolver
@@ -54,7 +21,9 @@ module ActiveRecord::Associations::Builder # :nodoc:
54
21
  end
55
22
 
56
23
  def self.table_name
57
- table_name_resolver.join_table
24
+ # Table name needs to be resolved lazily
25
+ # because RHS class might not have been loaded
26
+ @table_name ||= table_name_resolver.call
58
27
  end
59
28
 
60
29
  def self.compute_type(class_name)
@@ -77,14 +46,13 @@ module ActiveRecord::Associations::Builder # :nodoc:
77
46
  end
78
47
 
79
48
  private
80
-
81
- def self.suppress_composite_primary_key(pk)
82
- pk unless pk.is_a?(Array)
83
- end
49
+ def self.suppress_composite_primary_key(pk)
50
+ pk unless pk.is_a?(Array)
51
+ end
84
52
  }
85
53
 
86
54
  join_model.name = "HABTM_#{association_name.to_s.camelize}"
87
- join_model.table_name_resolver = habtm
55
+ join_model.table_name_resolver = -> { table_name }
88
56
  join_model.left_model = lhs_model
89
57
 
90
58
  join_model.add_left_association :left_side, anonymous_class: lhs_model
@@ -94,7 +62,7 @@ module ActiveRecord::Associations::Builder # :nodoc:
94
62
 
95
63
  def middle_reflection(join_model)
96
64
  middle_name = [lhs_model.name.downcase.pluralize,
97
- association_name].join('_'.freeze).gsub('::'.freeze, '_'.freeze).to_sym
65
+ association_name.to_s].sort.join("_").gsub("::", "_").to_sym
98
66
  middle_options = middle_options join_model
99
67
 
100
68
  HasMany.create_reflection(lhs_model,
@@ -104,30 +72,40 @@ module ActiveRecord::Associations::Builder # :nodoc:
104
72
  end
105
73
 
106
74
  private
75
+ def middle_options(join_model)
76
+ middle_options = {}
77
+ middle_options[:class_name] = "#{lhs_model.name}::#{join_model.name}"
78
+ if options.key? :foreign_key
79
+ middle_options[:foreign_key] = options[:foreign_key]
80
+ end
81
+ middle_options
82
+ end
107
83
 
108
- def middle_options(join_model)
109
- middle_options = {}
110
- middle_options[:class_name] = "#{lhs_model.name}::#{join_model.name}"
111
- middle_options[:source] = join_model.left_reflection.name
112
- if options.key? :foreign_key
113
- middle_options[:foreign_key] = options[:foreign_key]
84
+ def table_name
85
+ if options[:join_table]
86
+ options[:join_table].to_s
87
+ else
88
+ class_name = options.fetch(:class_name) {
89
+ association_name.to_s.camelize.singularize
90
+ }
91
+ klass = lhs_model.send(:compute_type, class_name.to_s)
92
+ [lhs_model.table_name, klass.table_name].sort.join("\0").gsub(/^(.*[._])(.+)\0\1(.+)/, '\1\2_\3').tr("\0", "_")
93
+ end
114
94
  end
115
- middle_options
116
- end
117
95
 
118
- def belongs_to_options(options)
119
- rhs_options = {}
96
+ def belongs_to_options(options)
97
+ rhs_options = {}
120
98
 
121
- if options.key? :class_name
122
- rhs_options[:foreign_key] = options[:class_name].to_s.foreign_key
123
- rhs_options[:class_name] = options[:class_name]
124
- end
99
+ if options.key? :class_name
100
+ rhs_options[:foreign_key] = options[:class_name].to_s.foreign_key
101
+ rhs_options[:class_name] = options[:class_name]
102
+ end
125
103
 
126
- if options.key? :association_foreign_key
127
- rhs_options[:foreign_key] = options[:association_foreign_key]
128
- end
104
+ if options.key? :association_foreign_key
105
+ rhs_options[:foreign_key] = options[:association_foreign_key]
106
+ end
129
107
 
130
- rhs_options
131
- end
108
+ rhs_options
109
+ end
132
110
  end
133
111
  end