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
  module ActiveRecord::Associations
2
4
  module ForeignAssociation # :nodoc:
3
5
  def foreign_key_present?
@@ -7,5 +9,25 @@ module ActiveRecord::Associations
7
9
  false
8
10
  end
9
11
  end
12
+
13
+ def nullified_owner_attributes
14
+ Hash.new.tap do |attrs|
15
+ attrs[reflection.foreign_key] = nil
16
+ attrs[reflection.type] = nil if reflection.type.present?
17
+ end
18
+ end
19
+
20
+ private
21
+ # Sets the owner attributes on the given record
22
+ def set_owner_attributes(record)
23
+ return if options[:through]
24
+
25
+ key = owner._read_attribute(reflection.join_foreign_key)
26
+ record._write_attribute(reflection.join_primary_key, key)
27
+
28
+ if reflection.type
29
+ record._write_attribute(reflection.type, owner.class.polymorphic_name)
30
+ end
31
+ end
10
32
  end
11
33
  end
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
- # = Active Record Has Many Association
3
4
  module Associations
5
+ # = Active Record Has Many Association
4
6
  # This is the proxy that handles a has many association.
5
7
  #
6
8
  # If the association has a <tt>:through</tt> option further specialization
@@ -16,25 +18,38 @@ module ActiveRecord
16
18
  when :restrict_with_error
17
19
  unless empty?
18
20
  record = owner.class.human_attribute_name(reflection.name).downcase
19
- message = owner.errors.generate_message(:base, :'restrict_dependent_destroy.many', record: record, raise: true) rescue nil
20
- if message
21
- ActiveSupport::Deprecation.warn(<<-MESSAGE.squish)
22
- The error key `:'restrict_dependent_destroy.many'` has been deprecated and will be removed in Rails 5.1.
23
- Please use `:'restrict_dependent_destroy.has_many'` instead.
24
- MESSAGE
25
- end
26
- owner.errors.add(:base, message || :'restrict_dependent_destroy.has_many', record: record)
21
+ owner.errors.add(:base, :'restrict_dependent_destroy.has_many', record: record)
27
22
  throw(:abort)
28
23
  end
29
24
 
30
- else
31
- if options[:dependent] == :destroy
32
- # No point in executing the counter update since we're going to destroy the parent anyway
33
- load_target.each { |t| t.destroyed_by_association = reflection }
34
- destroy_all
35
- else
36
- delete_all
25
+ when :destroy
26
+ # No point in executing the counter update since we're going to destroy the parent anyway
27
+ load_target.each { |t| t.destroyed_by_association = reflection }
28
+ destroy_all
29
+ when :destroy_async
30
+ load_target.each do |t|
31
+ t.destroyed_by_association = reflection
32
+ end
33
+
34
+ unless target.empty?
35
+ association_class = target.first.class
36
+ primary_key_column = association_class.primary_key.to_sym
37
+
38
+ ids = target.collect do |assoc|
39
+ assoc.public_send(primary_key_column)
40
+ end
41
+
42
+ enqueue_destroy_association(
43
+ owner_model_name: owner.class.to_s,
44
+ owner_id: owner.id,
45
+ association_class: reflection.klass.to_s,
46
+ association_ids: ids,
47
+ association_primary_key_column: primary_key_column,
48
+ ensuring_owner_was_method: options.fetch(:ensuring_owner_was, nil)
49
+ )
37
50
  end
51
+ else
52
+ delete_all
38
53
  end
39
54
  end
40
55
 
@@ -43,16 +58,7 @@ module ActiveRecord
43
58
  super
44
59
  end
45
60
 
46
- def empty?
47
- if reflection.has_cached_counter?
48
- size.zero?
49
- else
50
- super
51
- end
52
- end
53
-
54
61
  private
55
-
56
62
  # Returns the number of records in this collection.
57
63
  #
58
64
  # If the association has a counter cache it gets that value. Otherwise
@@ -68,15 +74,15 @@ module ActiveRecord
68
74
  # the loaded flag is set to true as well.
69
75
  def count_records
70
76
  count = if reflection.has_cached_counter?
71
- owner._read_attribute reflection.counter_cache_column
77
+ owner.read_attribute(reflection.counter_cache_column).to_i
72
78
  else
73
- scope.count
79
+ scope.count(:all)
74
80
  end
75
81
 
76
82
  # If there's nothing in the database and @target has no new records
77
83
  # we are certain the current target is an empty array. This is a
78
84
  # documented side-effect of the method that may avoid an extra SELECT.
79
- @target ||= [] and loaded! if count == 0
85
+ loaded! if count == 0
80
86
 
81
87
  [association_scope.limit_value, count].compact.min
82
88
  end
@@ -91,7 +97,7 @@ module ActiveRecord
91
97
  if reflection.counter_must_be_updated_by_has_many?
92
98
  counter = reflection.counter_cache_column
93
99
  owner.increment(counter, difference)
94
- owner.send(:clear_attribute_change, counter) # eww
100
+ owner.send(:"clear_#{counter}_change")
95
101
  end
96
102
  end
97
103
 
@@ -99,13 +105,14 @@ module ActiveRecord
99
105
  if method == :delete_all
100
106
  scope.delete_all
101
107
  else
102
- scope.update_all(reflection.foreign_key => nil)
108
+ scope.update_all(nullified_owner_attributes)
103
109
  end
104
110
  end
105
111
 
106
112
  def delete_or_nullify_all_records(method)
107
- count = delete_count(method, self.scope)
113
+ count = delete_count(method, scope)
108
114
  update_counter(-count)
115
+ count
109
116
  end
110
117
 
111
118
  # Deletes the records according to the <tt>:dependent</tt> option.
@@ -137,6 +144,14 @@ module ActiveRecord
137
144
  end
138
145
  saved_successfully
139
146
  end
147
+
148
+ def difference(a, b)
149
+ a - b
150
+ end
151
+
152
+ def intersection(a, b)
153
+ a & b
154
+ end
140
155
  end
141
156
  end
142
157
  end
@@ -1,14 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
- # = Active Record Has Many Through Association
3
4
  module Associations
5
+ # = Active Record Has Many Through Association
4
6
  class HasManyThroughAssociation < HasManyAssociation #:nodoc:
5
7
  include ThroughAssociation
6
8
 
7
9
  def initialize(owner, reflection)
8
10
  super
9
-
10
- @through_records = {}
11
- @through_association = nil
11
+ @through_records = {}.compare_by_identity
12
12
  end
13
13
 
14
14
  def concat(*records)
@@ -21,24 +21,10 @@ module ActiveRecord
21
21
  super
22
22
  end
23
23
 
24
- def concat_records(records)
25
- ensure_not_nested
26
-
27
- records = super(records, true)
28
-
29
- if owner.new_record? && records
30
- records.flatten.each do |record|
31
- build_through_record(record)
32
- end
33
- end
34
-
35
- records
36
- end
37
-
38
24
  def insert_record(record, validate = true, raise = false)
39
25
  ensure_not_nested
40
26
 
41
- if record.new_record? || record.changed?
27
+ if record.new_record? || record.has_changes_to_save?
42
28
  return unless super
43
29
  end
44
30
 
@@ -48,9 +34,18 @@ module ActiveRecord
48
34
  end
49
35
 
50
36
  private
37
+ def concat_records(records)
38
+ ensure_not_nested
39
+
40
+ records = super(records, true)
41
+
42
+ if owner.new_record? && records
43
+ records.flatten.each do |record|
44
+ build_through_record(record)
45
+ end
46
+ end
51
47
 
52
- def through_association
53
- @through_association ||= owner.association(through_reflection.name)
48
+ records
54
49
  end
55
50
 
56
51
  # The through record (built with build_record) is temporarily cached
@@ -59,40 +54,40 @@ module ActiveRecord
59
54
  # However, after insert_record has been called, the cache is cleared in
60
55
  # order to allow multiple instances of the same record in an association.
61
56
  def build_through_record(record)
62
- @through_records[record.object_id] ||= begin
57
+ @through_records[record] ||= begin
63
58
  ensure_mutable
64
59
 
65
- through_record = through_association.build(*options_for_through_record)
66
- through_record.send("#{source_reflection.name}=", record)
67
-
68
- if options[:source_type]
69
- through_record.send("#{source_reflection.foreign_type}=", options[:source_type])
70
- end
60
+ attributes = through_scope_attributes
61
+ attributes[source_reflection.name] = record
62
+ attributes[source_reflection.foreign_type] = options[:source_type] if options[:source_type]
71
63
 
72
- through_record
64
+ through_association.build(attributes)
73
65
  end
74
66
  end
75
67
 
76
- def options_for_through_record
77
- [through_scope_attributes]
78
- end
68
+ attr_reader :through_scope
79
69
 
80
70
  def through_scope_attributes
71
+ scope = through_scope || self.scope
81
72
  scope.where_values_hash(through_association.reflection.name.to_s).
82
73
  except!(through_association.reflection.foreign_key,
83
74
  through_association.reflection.klass.inheritance_column)
84
75
  end
85
76
 
86
77
  def save_through_record(record)
87
- build_through_record(record).save!
78
+ association = build_through_record(record)
79
+ if association.changed?
80
+ association.save!
81
+ end
88
82
  ensure
89
- @through_records.delete(record.object_id)
83
+ @through_records.delete(record)
90
84
  end
91
85
 
92
86
  def build_record(attributes)
93
87
  ensure_not_nested
94
88
 
95
- record = super(attributes)
89
+ @through_scope = scope
90
+ record = super
96
91
 
97
92
  inverse = source_reflection.inverse_of
98
93
  if inverse
@@ -104,6 +99,13 @@ module ActiveRecord
104
99
  end
105
100
 
106
101
  record
102
+ ensure
103
+ @through_scope = nil
104
+ end
105
+
106
+ def remove_records(existing_records, records, method)
107
+ super
108
+ delete_through_records(records)
107
109
  end
108
110
 
109
111
  def target_reflection_has_associated_record?
@@ -130,21 +132,15 @@ module ActiveRecord
130
132
 
131
133
  scope = through_association.scope
132
134
  scope.where! construct_join_attributes(*records)
135
+ scope = scope.where(through_scope_attributes)
133
136
 
134
137
  case method
135
138
  when :destroy
136
139
  if scope.klass.primary_key
137
- count = scope.destroy_all.length
140
+ count = scope.destroy_all.count(&:destroyed?)
138
141
  else
139
142
  scope.each(&:_run_destroy_callbacks)
140
-
141
- arel = scope.arel
142
-
143
- stmt = Arel::DeleteManager.new
144
- stmt.from scope.klass.arel_table
145
- stmt.wheres = arel.constraints
146
-
147
- count = scope.klass.connection.delete(stmt, 'SQL', scope.bound_attributes)
143
+ count = scope.delete_all
148
144
  end
149
145
  when :nullify
150
146
  count = scope.update_all(source_reflection.foreign_key => nil)
@@ -164,6 +160,30 @@ module ActiveRecord
164
160
  else
165
161
  update_counter(-count)
166
162
  end
163
+
164
+ count
165
+ end
166
+
167
+ def difference(a, b)
168
+ distribution = distribution(b)
169
+
170
+ a.reject { |record| mark_occurrence(distribution, record) }
171
+ end
172
+
173
+ def intersection(a, b)
174
+ distribution = distribution(b)
175
+
176
+ a.select { |record| mark_occurrence(distribution, record) }
177
+ end
178
+
179
+ def mark_occurrence(distribution, record)
180
+ distribution[record] > 0 && distribution[record] -= 1
181
+ end
182
+
183
+ def distribution(array)
184
+ array.each_with_object(Hash.new(0)) do |record, distribution|
185
+ distribution[record] += 1
186
+ end
167
187
  end
168
188
 
169
189
  def through_records_for(record)
@@ -188,13 +208,13 @@ module ActiveRecord
188
208
  end
189
209
  end
190
210
 
191
- @through_records.delete(record.object_id)
211
+ @through_records.delete(record)
192
212
  end
193
213
  end
194
214
 
195
215
  def find_target
196
216
  return [] unless target_reflection_has_associated_record?
197
- get_records
217
+ super
198
218
  end
199
219
 
200
220
  # NOTE - not sure that we can actually cope with inverses here
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
- # = Active Record Has One Association
3
4
  module Associations
5
+ # = Active Record Has One Association
4
6
  class HasOneAssociation < SingularAssociation #:nodoc:
5
7
  include ForeignAssociation
6
8
 
@@ -12,14 +14,7 @@ module ActiveRecord
12
14
  when :restrict_with_error
13
15
  if load_target
14
16
  record = owner.class.human_attribute_name(reflection.name).downcase
15
- message = owner.errors.generate_message(:base, :'restrict_dependent_destroy.one', record: record, raise: true) rescue nil
16
- if message
17
- ActiveSupport::Deprecation.warn(<<-MESSAGE.squish)
18
- The error key `:'restrict_dependent_destroy.one'` has been deprecated and will be removed in Rails 5.1.
19
- Please use `:'restrict_dependent_destroy.has_one'` instead.
20
- MESSAGE
21
- end
22
- owner.errors.add(:base, message || :'restrict_dependent_destroy.has_one', record: record)
17
+ owner.errors.add(:base, :'restrict_dependent_destroy.has_one', record: record)
23
18
  throw(:abort)
24
19
  end
25
20
 
@@ -28,49 +23,61 @@ module ActiveRecord
28
23
  end
29
24
  end
30
25
 
31
- def replace(record, save = true)
32
- raise_on_type_mismatch!(record) if record
33
- load_target
26
+ def delete(method = options[:dependent])
27
+ if load_target
28
+ case method
29
+ when :delete
30
+ target.delete
31
+ when :destroy
32
+ target.destroyed_by_association = reflection
33
+ target.destroy
34
+ throw(:abort) unless target.destroyed?
35
+ when :destroy_async
36
+ primary_key_column = target.class.primary_key.to_sym
37
+ id = target.public_send(primary_key_column)
38
+
39
+ enqueue_destroy_association(
40
+ owner_model_name: owner.class.to_s,
41
+ owner_id: owner.id,
42
+ association_class: reflection.klass.to_s,
43
+ association_ids: [id],
44
+ association_primary_key_column: primary_key_column,
45
+ ensuring_owner_was_method: options.fetch(:ensuring_owner_was, nil)
46
+ )
47
+ when :nullify
48
+ target.update_columns(nullified_owner_attributes) if target.persisted?
49
+ end
50
+ end
51
+ end
34
52
 
35
- return self.target if !(target || record)
53
+ private
54
+ def replace(record, save = true)
55
+ raise_on_type_mismatch!(record) if record
56
+
57
+ return target unless load_target || record
36
58
 
37
- assigning_another_record = target != record
38
- if assigning_another_record || record.changed?
39
- save &&= owner.persisted?
59
+ assigning_another_record = target != record
60
+ if assigning_another_record || record.has_changes_to_save?
61
+ save &&= owner.persisted?
40
62
 
41
- transaction_if(save) do
42
- remove_target!(options[:dependent]) if target && !target.destroyed? && assigning_another_record
63
+ transaction_if(save) do
64
+ remove_target!(options[:dependent]) if target && !target.destroyed? && assigning_another_record
43
65
 
44
- if record
45
- set_owner_attributes(record)
46
- set_inverse_instance(record)
66
+ if record
67
+ set_owner_attributes(record)
68
+ set_inverse_instance(record)
47
69
 
48
- if save && !record.save
49
- nullify_owner_attributes(record)
50
- set_owner_attributes(target) if target
51
- raise RecordNotSaved, "Failed to save the new associated #{reflection.name}."
70
+ if save && !record.save
71
+ nullify_owner_attributes(record)
72
+ set_owner_attributes(target) if target
73
+ raise RecordNotSaved, "Failed to save the new associated #{reflection.name}."
74
+ end
52
75
  end
53
76
  end
54
77
  end
55
- end
56
78
 
57
- self.target = record
58
- end
59
-
60
- def delete(method = options[:dependent])
61
- if load_target
62
- case method
63
- when :delete
64
- target.delete
65
- when :destroy
66
- target.destroy
67
- when :nullify
68
- target.update_columns(reflection.foreign_key => nil) if target.persisted?
69
- end
79
+ self.target = record
70
80
  end
71
- end
72
-
73
- private
74
81
 
75
82
  # The reason that the save param for replace is false, if for create (not just build),
76
83
  # is because the setting of the foreign keys is actually handled by the scoping when
@@ -82,18 +89,22 @@ module ActiveRecord
82
89
 
83
90
  def remove_target!(method)
84
91
  case method
85
- when :delete
86
- target.delete
87
- when :destroy
92
+ when :delete
93
+ target.delete
94
+ when :destroy
95
+ target.destroyed_by_association = reflection
96
+ if target.persisted?
88
97
  target.destroy
89
- else
90
- nullify_owner_attributes(target)
98
+ end
99
+ else
100
+ nullify_owner_attributes(target)
101
+ remove_inverse_instance(target)
91
102
 
92
- if target.persisted? && owner.persisted? && !target.save
93
- set_owner_attributes(target)
94
- raise RecordNotSaved, "Failed to remove the existing associated #{reflection.name}. " +
95
- "The record failed to save after its foreign key was set to nil."
96
- end
103
+ if target.persisted? && owner.persisted? && !target.save
104
+ set_owner_attributes(target)
105
+ raise RecordNotSaved, "Failed to remove the existing associated #{reflection.name}. " \
106
+ "The record failed to save after its foreign key was set to nil."
107
+ end
97
108
  end
98
109
  end
99
110
 
@@ -108,6 +119,14 @@ module ActiveRecord
108
119
  yield
109
120
  end
110
121
  end
122
+
123
+ def _create_record(attributes, raise_error = false, &block)
124
+ unless owner.persisted?
125
+ raise ActiveRecord::RecordNotSaved, "You cannot call create unless the parent is saved"
126
+ end
127
+
128
+ super
129
+ end
111
130
  end
112
131
  end
113
132
  end