activerecord 5.0.6 → 6.0.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 (358) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +638 -2023
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +8 -6
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record/aggregations.rb +249 -246
  8. data/lib/active_record/association_relation.rb +24 -13
  9. data/lib/active_record/associations/alias_tracker.rb +24 -33
  10. data/lib/active_record/associations/association.rb +119 -56
  11. data/lib/active_record/associations/association_scope.rb +94 -94
  12. data/lib/active_record/associations/belongs_to_association.rb +58 -42
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  14. data/lib/active_record/associations/builder/association.rb +18 -25
  15. data/lib/active_record/associations/builder/belongs_to.rb +43 -54
  16. data/lib/active_record/associations/builder/collection_association.rb +7 -18
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +42 -61
  18. data/lib/active_record/associations/builder/has_many.rb +4 -0
  19. data/lib/active_record/associations/builder/has_one.rb +37 -1
  20. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  21. data/lib/active_record/associations/collection_association.rb +80 -252
  22. data/lib/active_record/associations/collection_proxy.rb +158 -121
  23. data/lib/active_record/associations/foreign_association.rb +9 -0
  24. data/lib/active_record/associations/has_many_association.rb +23 -29
  25. data/lib/active_record/associations/has_many_through_association.rb +58 -44
  26. data/lib/active_record/associations/has_one_association.rb +59 -54
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +38 -90
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
  31. data/lib/active_record/associations/join_dependency.rb +134 -176
  32. data/lib/active_record/associations/preloader/association.rb +84 -125
  33. data/lib/active_record/associations/preloader/through_association.rb +82 -75
  34. data/lib/active_record/associations/preloader.rb +90 -102
  35. data/lib/active_record/associations/singular_association.rb +12 -45
  36. data/lib/active_record/associations/through_association.rb +26 -14
  37. data/lib/active_record/associations.rb +1603 -1592
  38. data/lib/active_record/attribute_assignment.rb +54 -60
  39. data/lib/active_record/attribute_decorators.rb +38 -15
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +12 -7
  41. data/lib/active_record/attribute_methods/dirty.rb +179 -109
  42. data/lib/active_record/attribute_methods/primary_key.rb +86 -91
  43. data/lib/active_record/attribute_methods/query.rb +4 -3
  44. data/lib/active_record/attribute_methods/read.rb +21 -49
  45. data/lib/active_record/attribute_methods/serialization.rb +30 -7
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -64
  47. data/lib/active_record/attribute_methods/write.rb +35 -33
  48. data/lib/active_record/attribute_methods.rb +66 -106
  49. data/lib/active_record/attributes.rb +38 -24
  50. data/lib/active_record/autosave_association.rb +53 -32
  51. data/lib/active_record/base.rb +27 -24
  52. data/lib/active_record/callbacks.rb +63 -33
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +11 -11
  55. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +553 -321
  56. data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
  57. data/lib/active_record/connection_adapters/abstract/database_statements.rb +213 -94
  58. data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -28
  59. data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -75
  60. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  61. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -27
  62. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +207 -126
  63. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  64. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +369 -199
  65. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
  66. data/lib/active_record/connection_adapters/abstract_adapter.rb +363 -202
  67. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +405 -551
  68. data/lib/active_record/connection_adapters/column.rb +41 -13
  69. data/lib/active_record/connection_adapters/connection_specification.rb +172 -138
  70. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
  71. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  72. data/lib/active_record/connection_adapters/mysql/database_statements.rb +143 -49
  73. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -22
  74. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  75. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +50 -45
  76. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
  77. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  78. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  79. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
  80. data/lib/active_record/connection_adapters/mysql2_adapter.rb +49 -30
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +22 -7
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +60 -54
  83. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -10
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +4 -2
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -17
  94. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  98. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +31 -9
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +34 -30
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  102. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +9 -4
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +35 -32
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +380 -300
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +10 -6
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +382 -275
  116. data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +120 -0
  119. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  120. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +74 -19
  121. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
  122. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  125. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +254 -262
  126. data/lib/active_record/connection_adapters/statement_pool.rb +9 -7
  127. data/lib/active_record/connection_handling.rb +159 -40
  128. data/lib/active_record/core.rb +202 -162
  129. data/lib/active_record/counter_cache.rb +57 -28
  130. data/lib/active_record/database_configurations/database_config.rb +37 -0
  131. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  132. data/lib/active_record/database_configurations/url_config.rb +79 -0
  133. data/lib/active_record/database_configurations.rb +233 -0
  134. data/lib/active_record/define_callbacks.rb +22 -0
  135. data/lib/active_record/dynamic_matchers.rb +87 -86
  136. data/lib/active_record/enum.rb +60 -23
  137. data/lib/active_record/errors.rb +114 -18
  138. data/lib/active_record/explain.rb +4 -3
  139. data/lib/active_record/explain_registry.rb +3 -1
  140. data/lib/active_record/explain_subscriber.rb +9 -4
  141. data/lib/active_record/fixture_set/file.rb +13 -8
  142. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  143. data/lib/active_record/fixture_set/render_context.rb +17 -0
  144. data/lib/active_record/fixture_set/table_row.rb +153 -0
  145. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  146. data/lib/active_record/fixtures.rb +195 -502
  147. data/lib/active_record/gem_version.rb +4 -2
  148. data/lib/active_record/inheritance.rb +151 -97
  149. data/lib/active_record/insert_all.rb +179 -0
  150. data/lib/active_record/integration.rb +116 -25
  151. data/lib/active_record/internal_metadata.rb +15 -18
  152. data/lib/active_record/legacy_yaml_adapter.rb +4 -2
  153. data/lib/active_record/locking/optimistic.rb +78 -87
  154. data/lib/active_record/locking/pessimistic.rb +18 -6
  155. data/lib/active_record/log_subscriber.rb +48 -29
  156. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  157. data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
  158. data/lib/active_record/middleware/database_selector.rb +75 -0
  159. data/lib/active_record/migration/command_recorder.rb +143 -97
  160. data/lib/active_record/migration/compatibility.rb +174 -56
  161. data/lib/active_record/migration/join_table.rb +8 -6
  162. data/lib/active_record/migration.rb +367 -300
  163. data/lib/active_record/model_schema.rb +145 -139
  164. data/lib/active_record/nested_attributes.rb +214 -201
  165. data/lib/active_record/no_touching.rb +10 -1
  166. data/lib/active_record/null_relation.rb +13 -34
  167. data/lib/active_record/persistence.rb +442 -72
  168. data/lib/active_record/query_cache.rb +15 -14
  169. data/lib/active_record/querying.rb +36 -23
  170. data/lib/active_record/railtie.rb +128 -36
  171. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  172. data/lib/active_record/railties/console_sandbox.rb +2 -0
  173. data/lib/active_record/railties/controller_runtime.rb +34 -33
  174. data/lib/active_record/railties/databases.rake +309 -177
  175. data/lib/active_record/readonly_attributes.rb +5 -4
  176. data/lib/active_record/reflection.rb +211 -249
  177. data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
  178. data/lib/active_record/relation/batches.rb +99 -52
  179. data/lib/active_record/relation/calculations.rb +211 -172
  180. data/lib/active_record/relation/delegation.rb +67 -65
  181. data/lib/active_record/relation/finder_methods.rb +208 -247
  182. data/lib/active_record/relation/from_clause.rb +2 -8
  183. data/lib/active_record/relation/merger.rb +78 -61
  184. data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
  185. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  186. data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
  187. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  188. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  189. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  190. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  191. data/lib/active_record/relation/predicate_builder.rb +86 -104
  192. data/lib/active_record/relation/query_attribute.rb +33 -2
  193. data/lib/active_record/relation/query_methods.rb +458 -329
  194. data/lib/active_record/relation/record_fetch_warning.rb +5 -3
  195. data/lib/active_record/relation/spawn_methods.rb +8 -7
  196. data/lib/active_record/relation/where_clause.rb +111 -95
  197. data/lib/active_record/relation/where_clause_factory.rb +6 -11
  198. data/lib/active_record/relation.rb +429 -318
  199. data/lib/active_record/result.rb +69 -39
  200. data/lib/active_record/runtime_registry.rb +5 -3
  201. data/lib/active_record/sanitization.rb +83 -99
  202. data/lib/active_record/schema.rb +7 -14
  203. data/lib/active_record/schema_dumper.rb +71 -69
  204. data/lib/active_record/schema_migration.rb +15 -5
  205. data/lib/active_record/scoping/default.rb +93 -95
  206. data/lib/active_record/scoping/named.rb +45 -25
  207. data/lib/active_record/scoping.rb +20 -19
  208. data/lib/active_record/secure_token.rb +4 -2
  209. data/lib/active_record/serialization.rb +2 -0
  210. data/lib/active_record/statement_cache.rb +63 -28
  211. data/lib/active_record/store.rb +121 -41
  212. data/lib/active_record/suppressor.rb +4 -1
  213. data/lib/active_record/table_metadata.rb +26 -20
  214. data/lib/active_record/tasks/database_tasks.rb +276 -85
  215. data/lib/active_record/tasks/mysql_database_tasks.rb +54 -90
  216. data/lib/active_record/tasks/postgresql_database_tasks.rb +78 -47
  217. data/lib/active_record/tasks/sqlite_database_tasks.rb +34 -16
  218. data/lib/active_record/test_databases.rb +23 -0
  219. data/lib/active_record/test_fixtures.rb +224 -0
  220. data/lib/active_record/timestamp.rb +70 -35
  221. data/lib/active_record/touch_later.rb +7 -4
  222. data/lib/active_record/transactions.rb +133 -149
  223. data/lib/active_record/translation.rb +3 -1
  224. data/lib/active_record/type/adapter_specific_registry.rb +44 -45
  225. data/lib/active_record/type/date.rb +2 -0
  226. data/lib/active_record/type/date_time.rb +2 -0
  227. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  228. data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
  229. data/lib/active_record/type/internal/timezone.rb +2 -0
  230. data/lib/active_record/type/json.rb +30 -0
  231. data/lib/active_record/type/serialized.rb +16 -8
  232. data/lib/active_record/type/text.rb +11 -0
  233. data/lib/active_record/type/time.rb +2 -1
  234. data/lib/active_record/type/type_map.rb +13 -15
  235. data/lib/active_record/type/unsigned_integer.rb +17 -0
  236. data/lib/active_record/type.rb +23 -17
  237. data/lib/active_record/type_caster/connection.rb +17 -12
  238. data/lib/active_record/type_caster/map.rb +5 -4
  239. data/lib/active_record/type_caster.rb +4 -2
  240. data/lib/active_record/validations/absence.rb +2 -0
  241. data/lib/active_record/validations/associated.rb +3 -1
  242. data/lib/active_record/validations/length.rb +2 -0
  243. data/lib/active_record/validations/presence.rb +4 -2
  244. data/lib/active_record/validations/uniqueness.rb +29 -42
  245. data/lib/active_record/validations.rb +7 -4
  246. data/lib/active_record/version.rb +3 -1
  247. data/lib/active_record.rb +36 -22
  248. data/lib/arel/alias_predication.rb +9 -0
  249. data/lib/arel/attributes/attribute.rb +37 -0
  250. data/lib/arel/attributes.rb +22 -0
  251. data/lib/arel/collectors/bind.rb +24 -0
  252. data/lib/arel/collectors/composite.rb +31 -0
  253. data/lib/arel/collectors/plain_string.rb +20 -0
  254. data/lib/arel/collectors/sql_string.rb +20 -0
  255. data/lib/arel/collectors/substitute_binds.rb +28 -0
  256. data/lib/arel/crud.rb +42 -0
  257. data/lib/arel/delete_manager.rb +18 -0
  258. data/lib/arel/errors.rb +9 -0
  259. data/lib/arel/expressions.rb +29 -0
  260. data/lib/arel/factory_methods.rb +49 -0
  261. data/lib/arel/insert_manager.rb +49 -0
  262. data/lib/arel/math.rb +45 -0
  263. data/lib/arel/nodes/and.rb +32 -0
  264. data/lib/arel/nodes/ascending.rb +23 -0
  265. data/lib/arel/nodes/binary.rb +52 -0
  266. data/lib/arel/nodes/bind_param.rb +36 -0
  267. data/lib/arel/nodes/case.rb +55 -0
  268. data/lib/arel/nodes/casted.rb +50 -0
  269. data/lib/arel/nodes/comment.rb +29 -0
  270. data/lib/arel/nodes/count.rb +12 -0
  271. data/lib/arel/nodes/delete_statement.rb +45 -0
  272. data/lib/arel/nodes/descending.rb +23 -0
  273. data/lib/arel/nodes/equality.rb +18 -0
  274. data/lib/arel/nodes/extract.rb +24 -0
  275. data/lib/arel/nodes/false.rb +16 -0
  276. data/lib/arel/nodes/full_outer_join.rb +8 -0
  277. data/lib/arel/nodes/function.rb +44 -0
  278. data/lib/arel/nodes/grouping.rb +8 -0
  279. data/lib/arel/nodes/in.rb +8 -0
  280. data/lib/arel/nodes/infix_operation.rb +80 -0
  281. data/lib/arel/nodes/inner_join.rb +8 -0
  282. data/lib/arel/nodes/insert_statement.rb +37 -0
  283. data/lib/arel/nodes/join_source.rb +20 -0
  284. data/lib/arel/nodes/matches.rb +18 -0
  285. data/lib/arel/nodes/named_function.rb +23 -0
  286. data/lib/arel/nodes/node.rb +50 -0
  287. data/lib/arel/nodes/node_expression.rb +13 -0
  288. data/lib/arel/nodes/outer_join.rb +8 -0
  289. data/lib/arel/nodes/over.rb +15 -0
  290. data/lib/arel/nodes/regexp.rb +16 -0
  291. data/lib/arel/nodes/right_outer_join.rb +8 -0
  292. data/lib/arel/nodes/select_core.rb +67 -0
  293. data/lib/arel/nodes/select_statement.rb +41 -0
  294. data/lib/arel/nodes/sql_literal.rb +16 -0
  295. data/lib/arel/nodes/string_join.rb +11 -0
  296. data/lib/arel/nodes/table_alias.rb +27 -0
  297. data/lib/arel/nodes/terminal.rb +16 -0
  298. data/lib/arel/nodes/true.rb +16 -0
  299. data/lib/arel/nodes/unary.rb +45 -0
  300. data/lib/arel/nodes/unary_operation.rb +20 -0
  301. data/lib/arel/nodes/unqualified_column.rb +22 -0
  302. data/lib/arel/nodes/update_statement.rb +41 -0
  303. data/lib/arel/nodes/values_list.rb +9 -0
  304. data/lib/arel/nodes/window.rb +126 -0
  305. data/lib/arel/nodes/with.rb +11 -0
  306. data/lib/arel/nodes.rb +68 -0
  307. data/lib/arel/order_predications.rb +13 -0
  308. data/lib/arel/predications.rb +257 -0
  309. data/lib/arel/select_manager.rb +271 -0
  310. data/lib/arel/table.rb +110 -0
  311. data/lib/arel/tree_manager.rb +72 -0
  312. data/lib/arel/update_manager.rb +34 -0
  313. data/lib/arel/visitors/depth_first.rb +204 -0
  314. data/lib/arel/visitors/dot.rb +297 -0
  315. data/lib/arel/visitors/ibm_db.rb +34 -0
  316. data/lib/arel/visitors/informix.rb +62 -0
  317. data/lib/arel/visitors/mssql.rb +157 -0
  318. data/lib/arel/visitors/mysql.rb +83 -0
  319. data/lib/arel/visitors/oracle.rb +159 -0
  320. data/lib/arel/visitors/oracle12.rb +66 -0
  321. data/lib/arel/visitors/postgresql.rb +110 -0
  322. data/lib/arel/visitors/sqlite.rb +39 -0
  323. data/lib/arel/visitors/to_sql.rb +889 -0
  324. data/lib/arel/visitors/visitor.rb +46 -0
  325. data/lib/arel/visitors/where_sql.rb +23 -0
  326. data/lib/arel/visitors.rb +20 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +58 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -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/migration_generator.rb +37 -35
  332. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
  334. data/lib/rails/generators/active_record/migration.rb +17 -2
  335. data/lib/rails/generators/active_record/model/model_generator.rb +9 -29
  336. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  337. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  338. data/lib/rails/generators/active_record.rb +7 -5
  339. metadata +133 -50
  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/user_provided_default.rb +0 -28
  348. data/lib/active_record/attribute.rb +0 -213
  349. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  350. data/lib/active_record/attribute_set/builder.rb +0 -130
  351. data/lib/active_record/attribute_set.rb +0 -110
  352. data/lib/active_record/collection_cache_key.rb +0 -50
  353. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  354. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  355. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  356. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  357. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  358. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,7 +1,6 @@
1
- require 'active_support/core_ext/enumerable'
2
- require 'active_support/core_ext/string/filters'
3
- require 'mutex_m'
4
- require 'concurrent/map'
1
+ # frozen_string_literal: true
2
+
3
+ require "mutex_m"
5
4
 
6
5
  module ActiveRecord
7
6
  # = Active Record Attribute Methods
@@ -23,18 +22,11 @@ module ActiveRecord
23
22
  delegate :column_for_attribute, to: :class
24
23
  end
25
24
 
26
- AttrNames = Module.new {
27
- def self.set_name_cache(name, value)
28
- const_name = "ATTR_#{name}"
29
- unless const_defined? const_name
30
- const_set const_name, value.dup.freeze
31
- end
32
- end
33
- }
25
+ RESTRICTED_CLASS_METHODS = %w(private public protected allocate new name parent superclass)
34
26
 
35
- BLACKLISTED_CLASS_METHODS = %w(private public protected allocate new name parent superclass)
36
-
37
- class GeneratedAttributeMethods < Module; end # :nodoc:
27
+ class GeneratedAttributeMethods < Module #:nodoc:
28
+ include Mutex_m
29
+ end
38
30
 
39
31
  module ClassMethods
40
32
  def inherited(child_class) #:nodoc:
@@ -43,7 +35,8 @@ module ActiveRecord
43
35
  end
44
36
 
45
37
  def initialize_generated_modules # :nodoc:
46
- @generated_attribute_methods = GeneratedAttributeMethods.new { extend Mutex_m }
38
+ @generated_attribute_methods = const_set(:GeneratedAttributeMethods, GeneratedAttributeMethods.new)
39
+ private_constant :GeneratedAttributeMethods
47
40
  @attribute_methods_generated = false
48
41
  include @generated_attribute_methods
49
42
 
@@ -58,11 +51,10 @@ module ActiveRecord
58
51
  # attribute methods.
59
52
  generated_attribute_methods.synchronize do
60
53
  return false if @attribute_methods_generated
61
- superclass.define_attribute_methods unless self == base_class
54
+ superclass.define_attribute_methods unless base_class?
62
55
  super(attribute_names)
63
56
  @attribute_methods_generated = true
64
57
  end
65
- true
66
58
  end
67
59
 
68
60
  def undefine_attribute_methods # :nodoc:
@@ -123,7 +115,7 @@ module ActiveRecord
123
115
  # A class method is 'dangerous' if it is already (re)defined by Active Record, but
124
116
  # not by any ancestors. (So 'puts' is not dangerous but 'new' is.)
125
117
  def dangerous_class_method?(method_name)
126
- BLACKLISTED_CLASS_METHODS.include?(method_name.to_s) || class_method_defined_within?(method_name, Base)
118
+ RESTRICTED_CLASS_METHODS.include?(method_name.to_s) || class_method_defined_within?(method_name, Base)
127
119
  end
128
120
 
129
121
  def class_method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc:
@@ -148,7 +140,7 @@ module ActiveRecord
148
140
  # Person.attribute_method?(:age=) # => true
149
141
  # Person.attribute_method?(:nothing) # => false
150
142
  def attribute_method?(attribute)
151
- super || (table_exists? && column_names.include?(attribute.to_s.sub(/=$/, '')))
143
+ super || (table_exists? && column_names.include?(attribute.to_s.sub(/=$/, "")))
152
144
  end
153
145
 
154
146
  # Returns an array of column names as strings if it's not an abstract class and
@@ -161,10 +153,10 @@ module ActiveRecord
161
153
  # # => ["id", "created_at", "updated_at", "name", "age"]
162
154
  def attribute_names
163
155
  @attribute_names ||= if !abstract_class? && table_exists?
164
- attribute_types.keys
165
- else
166
- []
167
- end
156
+ attribute_types.keys
157
+ else
158
+ []
159
+ end
168
160
  end
169
161
 
170
162
  # Returns true if the given attribute exists, otherwise false.
@@ -209,34 +201,27 @@ module ActiveRecord
209
201
  # end
210
202
  #
211
203
  # person = Person.new
212
- # person.respond_to(:name) # => true
213
- # person.respond_to(:name=) # => true
214
- # person.respond_to(:name?) # => true
215
- # person.respond_to('age') # => true
216
- # person.respond_to('age=') # => true
217
- # person.respond_to('age?') # => true
218
- # person.respond_to(:nothing) # => false
204
+ # person.respond_to?(:name) # => true
205
+ # person.respond_to?(:name=) # => true
206
+ # person.respond_to?(:name?) # => true
207
+ # person.respond_to?('age') # => true
208
+ # person.respond_to?('age=') # => true
209
+ # person.respond_to?('age?') # => true
210
+ # person.respond_to?(:nothing) # => false
219
211
  def respond_to?(name, include_private = false)
220
212
  return false unless super
221
213
 
222
- case name
223
- when :to_partial_path
224
- name = "to_partial_path".freeze
225
- when :to_model
226
- name = "to_model".freeze
227
- else
228
- name = name.to_s
229
- end
230
-
231
214
  # If the result is true then check for the select case.
232
215
  # For queries selecting a subset of columns, return false for unselected columns.
233
216
  # We check defined?(@attributes) not to issue warnings if called on objects that
234
217
  # have been allocated but not yet initialized.
235
- if defined?(@attributes) && self.class.column_names.include?(name)
236
- return has_attribute?(name)
218
+ if defined?(@attributes)
219
+ if name = self.class.symbol_column_to_string(name.to_sym)
220
+ return has_attribute?(name)
221
+ end
237
222
  end
238
223
 
239
- return true
224
+ true
240
225
  end
241
226
 
242
227
  # Returns +true+ if the given attribute is in the attributes hash, otherwise +false+.
@@ -293,15 +278,8 @@ module ActiveRecord
293
278
  # person.attribute_for_inspect(:tag_ids)
294
279
  # # => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]"
295
280
  def attribute_for_inspect(attr_name)
296
- value = read_attribute(attr_name)
297
-
298
- if value.is_a?(String) && value.length > 50
299
- "#{value[0, 50]}...".inspect
300
- elsif value.is_a?(Date) || value.is_a?(Time)
301
- %("#{value.to_s(:db)}")
302
- else
303
- value.inspect
304
- end
281
+ value = _read_attribute(attr_name)
282
+ format_for_inspect(value)
305
283
  end
306
284
 
307
285
  # Returns +true+ if the specified +attribute+ has been set by the user or by a
@@ -330,8 +308,6 @@ module ActiveRecord
330
308
  #
331
309
  # Note: +:id+ is always present.
332
310
  #
333
- # Alias for the #read_attribute method.
334
- #
335
311
  # class Person < ActiveRecord::Base
336
312
  # belongs_to :organization
337
313
  # end
@@ -394,67 +370,51 @@ module ActiveRecord
394
370
  @attributes.accessed
395
371
  end
396
372
 
397
- protected
398
-
399
- def clone_attribute_value(reader_method, attribute_name) # :nodoc:
400
- value = send(reader_method, attribute_name)
401
- value.duplicable? ? value.clone : value
402
- rescue TypeError, NoMethodError
403
- value
404
- end
405
-
406
- def arel_attributes_with_values_for_create(attribute_names) # :nodoc:
407
- arel_attributes_with_values(attributes_for_create(attribute_names))
408
- end
409
-
410
- def arel_attributes_with_values_for_update(attribute_names) # :nodoc:
411
- arel_attributes_with_values(attributes_for_update(attribute_names))
412
- end
413
-
414
- def attribute_method?(attr_name) # :nodoc:
415
- # We check defined? because Syck calls respond_to? before actually calling initialize.
416
- defined?(@attributes) && @attributes.key?(attr_name)
417
- end
418
-
419
373
  private
374
+ def attribute_method?(attr_name)
375
+ # We check defined? because Syck calls respond_to? before actually calling initialize.
376
+ defined?(@attributes) && @attributes.key?(attr_name)
377
+ end
420
378
 
421
- # Returns a Hash of the Arel::Attributes and attribute values that have been
422
- # typecasted for use in an Arel insert/update method.
423
- def arel_attributes_with_values(attribute_names)
424
- attrs = {}
425
- arel_table = self.class.arel_table
426
-
427
- attribute_names.each do |name|
428
- attrs[arel_table[name]] = typecasted_attribute_value(name)
379
+ def attributes_with_values(attribute_names)
380
+ attribute_names.each_with_object({}) do |name, attrs|
381
+ attrs[name] = _read_attribute(name)
382
+ end
429
383
  end
430
- attrs
431
- end
432
384
 
433
- # Filters the primary keys and readonly attributes from the attribute names.
434
- def attributes_for_update(attribute_names)
435
- attribute_names.reject do |name|
436
- readonly_attribute?(name)
385
+ # Filters the primary keys and readonly attributes from the attribute names.
386
+ def attributes_for_update(attribute_names)
387
+ attribute_names &= self.class.column_names
388
+ attribute_names.delete_if do |name|
389
+ readonly_attribute?(name)
390
+ end
437
391
  end
438
- end
439
392
 
440
- # Filters out the primary keys, from the attribute names, when the primary
441
- # key is to be generated (e.g. the id attribute has no value).
442
- def attributes_for_create(attribute_names)
443
- attribute_names.reject do |name|
444
- pk_attribute?(name) && id.nil?
393
+ # Filters out the primary keys, from the attribute names, when the primary
394
+ # key is to be generated (e.g. the id attribute has no value).
395
+ def attributes_for_create(attribute_names)
396
+ attribute_names &= self.class.column_names
397
+ attribute_names.delete_if do |name|
398
+ pk_attribute?(name) && id.nil?
399
+ end
445
400
  end
446
- end
447
401
 
448
- def readonly_attribute?(name)
449
- self.class.readonly_attributes.include?(name)
450
- end
402
+ def format_for_inspect(value)
403
+ if value.is_a?(String) && value.length > 50
404
+ "#{value[0, 50]}...".inspect
405
+ elsif value.is_a?(Date) || value.is_a?(Time)
406
+ %("#{value.to_s(:db)}")
407
+ else
408
+ value.inspect
409
+ end
410
+ end
451
411
 
452
- def pk_attribute?(name)
453
- name == self.class.primary_key
454
- end
412
+ def readonly_attribute?(name)
413
+ self.class.readonly_attributes.include?(name)
414
+ end
455
415
 
456
- def typecasted_attribute_value(name)
457
- _read_attribute(name)
458
- end
416
+ def pk_attribute?(name)
417
+ name == @primary_key
418
+ end
459
419
  end
460
420
  end
@@ -1,4 +1,6 @@
1
- require 'active_record/attribute/user_provided_default'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_model/attribute/user_provided_default"
2
4
 
3
5
  module ActiveRecord
4
6
  # See ActiveRecord::Attributes::ClassMethods for documentation
@@ -6,8 +8,7 @@ module ActiveRecord
6
8
  extend ActiveSupport::Concern
7
9
 
8
10
  included do
9
- class_attribute :attributes_to_define_after_schema_loads, instance_accessor: false # :internal:
10
- self.attributes_to_define_after_schema_loads = {}
11
+ class_attribute :attributes_to_define_after_schema_loads, instance_accessor: false, default: {} # :internal:
11
12
  end
12
13
 
13
14
  module ClassMethods
@@ -40,6 +41,9 @@ module ActiveRecord
40
41
  # +range+ (PostgreSQL only) specifies that the type should be a range (see the
41
42
  # examples below).
42
43
  #
44
+ # When using a symbol for +cast_type+, extra options are forwarded to the
45
+ # constructor of the type object.
46
+ #
43
47
  # ==== Examples
44
48
  #
45
49
  # The type detected by Active Record can be overridden.
@@ -56,7 +60,7 @@ module ActiveRecord
56
60
  # store_listing = StoreListing.new(price_in_cents: '10.1')
57
61
  #
58
62
  # # before
59
- # store_listing.price_in_cents # => BigDecimal.new(10.1)
63
+ # store_listing.price_in_cents # => BigDecimal(10.1)
60
64
  #
61
65
  # class StoreListing < ActiveRecord::Base
62
66
  # attribute :price_in_cents, :integer
@@ -111,12 +115,22 @@ module ActiveRecord
111
115
  # my_float_range: 1.0..3.5
112
116
  # }
113
117
  #
118
+ # Passing options to the type constructor
119
+ #
120
+ # # app/models/my_model.rb
121
+ # class MyModel < ActiveRecord::Base
122
+ # attribute :small_int, :integer, limit: 2
123
+ # end
124
+ #
125
+ # MyModel.create(small_int: 65537)
126
+ # # => Error: 65537 is out of range for the limit of two bytes
127
+ #
114
128
  # ==== Creating Custom Types
115
129
  #
116
130
  # Users may also define their own custom types, as long as they respond
117
131
  # to the methods defined on the value type. The method +deserialize+ or
118
132
  # +cast+ will be called on your type object, with raw input from the
119
- # database or from your controllers. See ActiveRecord::Type::Value for the
133
+ # database or from your controllers. See ActiveModel::Type::Value for the
120
134
  # expected API. It is recommended that your type objects inherit from an
121
135
  # existing type, or from ActiveRecord::Type::Value
122
136
  #
@@ -143,7 +157,7 @@ module ActiveRecord
143
157
  # store_listing.price_in_cents # => 1000
144
158
  #
145
159
  # For more details on creating custom types, see the documentation for
146
- # ActiveRecord::Type::Value. For more details on registering your types
160
+ # ActiveModel::Type::Value. For more details on registering your types
147
161
  # to be referenced by a symbol, see ActiveRecord::Type.register. You can
148
162
  # also pass a type object directly, in place of a symbol.
149
163
  #
@@ -190,8 +204,8 @@ module ActiveRecord
190
204
  # The type of an attribute is given the opportunity to change how dirty
191
205
  # tracking is performed. The methods +changed?+ and +changed_in_place?+
192
206
  # will be called from ActiveModel::Dirty. See the documentation for those
193
- # methods in ActiveRecord::Type::Value for more details.
194
- def attribute(name, cast_type, **options)
207
+ # methods in ActiveModel::Type::Value for more details.
208
+ def attribute(name, cast_type = Type::Value.new, **options)
195
209
  name = name.to_s
196
210
  reload_schema_from_cache
197
211
 
@@ -242,24 +256,24 @@ module ActiveRecord
242
256
 
243
257
  private
244
258
 
245
- NO_DEFAULT_PROVIDED = Object.new # :nodoc:
246
- private_constant :NO_DEFAULT_PROVIDED
259
+ NO_DEFAULT_PROVIDED = Object.new # :nodoc:
260
+ private_constant :NO_DEFAULT_PROVIDED
247
261
 
248
- def define_default_attribute(name, value, type, from_user:)
249
- if value == NO_DEFAULT_PROVIDED
250
- default_attribute = _default_attributes[name].with_type(type)
251
- elsif from_user
252
- default_attribute = Attribute::UserProvidedDefault.new(
253
- name,
254
- value,
255
- type,
256
- _default_attributes.fetch(name.to_s) { nil },
257
- )
258
- else
259
- default_attribute = Attribute.from_database(name, value, type)
262
+ def define_default_attribute(name, value, type, from_user:)
263
+ if value == NO_DEFAULT_PROVIDED
264
+ default_attribute = _default_attributes[name].with_type(type)
265
+ elsif from_user
266
+ default_attribute = ActiveModel::Attribute::UserProvidedDefault.new(
267
+ name,
268
+ value,
269
+ type,
270
+ _default_attributes.fetch(name.to_s) { nil },
271
+ )
272
+ else
273
+ default_attribute = ActiveModel::Attribute.from_database(name, value, type)
274
+ end
275
+ _default_attributes[name] = default_attribute
260
276
  end
261
- _default_attributes[name] = default_attribute
262
- end
263
277
  end
264
278
  end
265
279
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # = Active Record Autosave Association
3
5
  #
@@ -140,24 +142,23 @@ module ActiveRecord
140
142
 
141
143
  included do
142
144
  Associations::Builder::Association.extensions << AssociationBuilderExtension
143
- mattr_accessor :index_nested_attribute_errors, instance_writer: false
144
- self.index_nested_attribute_errors = false
145
+ mattr_accessor :index_nested_attribute_errors, instance_writer: false, default: false
145
146
  end
146
147
 
147
148
  module ClassMethods # :nodoc:
148
149
  private
149
150
 
150
151
  def define_non_cyclic_method(name, &block)
151
- return if method_defined?(name)
152
+ return if instance_methods(false).include?(name)
152
153
  define_method(name) do |*args|
153
154
  result = true; @_already_called ||= {}
154
155
  # Loop prevention for validation of associations
155
156
  unless @_already_called[name]
156
157
  begin
157
- @_already_called[name]=true
158
+ @_already_called[name] = true
158
159
  result = instance_eval(&block)
159
160
  ensure
160
- @_already_called[name]=false
161
+ @_already_called[name] = false
161
162
  end
162
163
  end
163
164
 
@@ -181,6 +182,7 @@ module ActiveRecord
181
182
 
182
183
  if reflection.collection?
183
184
  before_save :before_save_collection_association
185
+ after_save :after_save_collection_association
184
186
 
185
187
  define_non_cyclic_method(save_method) { save_collection_association(reflection) }
186
188
  # Doesn't use after_save as that would save associations added in after_create/after_update twice
@@ -215,13 +217,7 @@ module ActiveRecord
215
217
  method = :validate_single_association
216
218
  end
217
219
 
218
- define_non_cyclic_method(validation_method) do
219
- send(method, reflection)
220
- # TODO: remove the following line as soon as the return value of
221
- # callbacks is ignored, that is, returning `false` does not
222
- # display a deprecation warning or halts the callback chain.
223
- true
224
- end
220
+ define_non_cyclic_method(validation_method) { send(method, reflection) }
225
221
  validate validation_method
226
222
  after_validation :_ensure_no_duplicate_errors
227
223
  end
@@ -267,7 +263,7 @@ module ActiveRecord
267
263
  # Returns whether or not this record has been changed in any way (including whether
268
264
  # any of its nested autosave associations are likewise changed)
269
265
  def changed_for_autosave?
270
- new_record? || changed? || marked_for_destruction? || nested_records_changed_for_autosave?
266
+ new_record? || has_changes_to_save? || marked_for_destruction? || nested_records_changed_for_autosave?
271
267
  end
272
268
 
273
269
  private
@@ -276,7 +272,7 @@ module ActiveRecord
276
272
  # or saved. If +autosave+ is +false+ only new records will be returned,
277
273
  # unless the parent is/was a new record itself.
278
274
  def associated_records_to_validate_or_save(association, new_record, autosave)
279
- if new_record
275
+ if new_record || custom_validation_context?
280
276
  association && association.target
281
277
  elsif autosave
282
278
  association.target.find_all(&:changed_for_autosave?)
@@ -308,7 +304,7 @@ module ActiveRecord
308
304
  def validate_single_association(reflection)
309
305
  association = association_instance_get(reflection.name)
310
306
  record = association && association.reader
311
- association_valid?(reflection, record) if record
307
+ association_valid?(reflection, record) if record && (record.changed_for_autosave? || custom_validation_context?)
312
308
  end
313
309
 
314
310
  # Validate the associated records if <tt>:validate</tt> or
@@ -325,12 +321,12 @@ module ActiveRecord
325
321
  # Returns whether or not the association is valid and applies any errors to
326
322
  # the parent, <tt>self</tt>, if it wasn't. Skips any <tt>:autosave</tt>
327
323
  # enabled records if they're marked_for_destruction? or destroyed.
328
- def association_valid?(reflection, record, index=nil)
324
+ def association_valid?(reflection, record, index = nil)
329
325
  return true if record.destroyed? || (reflection.options[:autosave] && record.marked_for_destruction?)
330
326
 
331
- validation_context = self.validation_context unless [:create, :update].include?(self.validation_context)
327
+ context = validation_context if custom_validation_context?
332
328
 
333
- unless valid = record.valid?(validation_context)
329
+ unless valid = record.valid?(context)
334
330
  if reflection.options[:autosave]
335
331
  indexed_attribute = !index.nil? && (reflection.options[:index_errors] || ActiveRecord::Base.index_nested_attribute_errors)
336
332
 
@@ -368,7 +364,10 @@ module ActiveRecord
368
364
  # association whether or not the parent was a new record before saving.
369
365
  def before_save_collection_association
370
366
  @new_record_before_save = new_record?
371
- true
367
+ end
368
+
369
+ def after_save_collection_association
370
+ @new_record_before_save = false
372
371
  end
373
372
 
374
373
  # Saves any new associated records, or all loaded autosave associations if
@@ -383,7 +382,14 @@ module ActiveRecord
383
382
  if association = association_instance_get(reflection.name)
384
383
  autosave = reflection.options[:autosave]
385
384
 
386
- if records = associated_records_to_validate_or_save(association, @new_record_before_save, autosave)
385
+ # By saving the instance variable in a local variable,
386
+ # we make the whole callback re-entrant.
387
+ new_record_before_save = @new_record_before_save
388
+
389
+ # reconstruct the scope now that we know the owner's id
390
+ association.reset_scope
391
+
392
+ if records = associated_records_to_validate_or_save(association, new_record_before_save, autosave)
387
393
  if autosave
388
394
  records_to_destroy = records.select(&:marked_for_destruction?)
389
395
  records_to_destroy.each { |record| association.destroy(record) }
@@ -395,22 +401,24 @@ module ActiveRecord
395
401
 
396
402
  saved = true
397
403
 
398
- if autosave != false && (@new_record_before_save || record.new_record?)
404
+ if autosave != false && (new_record_before_save || record.new_record?)
399
405
  if autosave
400
406
  saved = association.insert_record(record, false)
401
- else
402
- association.insert_record(record) unless reflection.nested?
407
+ elsif !reflection.nested?
408
+ association_saved = association.insert_record(record)
409
+
410
+ if reflection.validate?
411
+ errors.add(reflection.name) unless association_saved
412
+ saved = association_saved
413
+ end
403
414
  end
404
415
  elsif autosave
405
- saved = record.save(:validate => false)
416
+ saved = record.save(validate: false)
406
417
  end
407
418
 
408
- raise ActiveRecord::Rollback unless saved
419
+ raise(RecordInvalid.new(association.owner)) unless saved
409
420
  end
410
421
  end
411
-
412
- # reconstruct the scope now that we know the owner's id
413
- association.reset_scope if association.respond_to?(:reset_scope)
414
422
  end
415
423
  end
416
424
 
@@ -437,9 +445,12 @@ module ActiveRecord
437
445
  if (autosave && record.changed_for_autosave?) || new_record? || record_changed?(reflection, record, key)
438
446
  unless reflection.through_reflection
439
447
  record[reflection.foreign_key] = key
448
+ if inverse_reflection = reflection.inverse_of
449
+ record.association(inverse_reflection.name).loaded!
450
+ end
440
451
  end
441
452
 
442
- saved = record.save(:validate => !autosave)
453
+ saved = record.save(validate: !autosave)
443
454
  raise ActiveRecord::Rollback if !saved && autosave
444
455
  saved
445
456
  end
@@ -450,8 +461,14 @@ module ActiveRecord
450
461
  # If the record is new or it has changed, returns true.
451
462
  def record_changed?(reflection, record, key)
452
463
  record.new_record? ||
453
- (record.has_attribute?(reflection.foreign_key) && record[reflection.foreign_key] != key) ||
454
- record.attribute_changed?(reflection.foreign_key)
464
+ association_foreign_key_changed?(reflection, record, key) ||
465
+ record.will_save_change_to_attribute?(reflection.foreign_key)
466
+ end
467
+
468
+ def association_foreign_key_changed?(reflection, record, key)
469
+ return false if reflection.through_reflection?
470
+
471
+ record.has_attribute?(reflection.foreign_key) && record[reflection.foreign_key] != key
455
472
  end
456
473
 
457
474
  # Saves the associated record if it's new or <tt>:autosave</tt> is enabled.
@@ -469,7 +486,7 @@ module ActiveRecord
469
486
  self[reflection.foreign_key] = nil
470
487
  record.destroy
471
488
  elsif autosave != false
472
- saved = record.save(:validate => !autosave) if record.new_record? || (autosave && record.changed_for_autosave?)
489
+ saved = record.save(validate: !autosave) if record.new_record? || (autosave && record.changed_for_autosave?)
473
490
 
474
491
  if association.updated?
475
492
  association_id = record.send(reflection.options[:primary_key] || :id)
@@ -482,6 +499,10 @@ module ActiveRecord
482
499
  end
483
500
  end
484
501
 
502
+ def custom_validation_context?
503
+ validation_context && [:create, :update].exclude?(validation_context)
504
+ end
505
+
485
506
  def _ensure_no_duplicate_errors
486
507
  errors.messages.each_key do |attribute|
487
508
  errors[attribute].uniq!
@@ -1,25 +1,28 @@
1
- require 'yaml'
2
- require 'active_support/benchmarkable'
3
- require 'active_support/dependencies'
4
- require 'active_support/descendants_tracker'
5
- require 'active_support/time'
6
- require 'active_support/core_ext/module/attribute_accessors'
7
- require 'active_support/core_ext/array/extract_options'
8
- require 'active_support/core_ext/hash/deep_merge'
9
- require 'active_support/core_ext/hash/slice'
10
- require 'active_support/core_ext/hash/transform_values'
11
- require 'active_support/core_ext/string/behavior'
12
- require 'active_support/core_ext/kernel/singleton_class'
13
- require 'active_support/core_ext/module/introspection'
14
- require 'active_support/core_ext/object/duplicable'
15
- require 'active_support/core_ext/class/subclasses'
16
- require 'active_record/attribute_decorators'
17
- require 'active_record/errors'
18
- require 'active_record/log_subscriber'
19
- require 'active_record/explain_subscriber'
20
- require 'active_record/relation/delegation'
21
- require 'active_record/attributes'
22
- require 'active_record/type_caster'
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+ require "active_support/benchmarkable"
5
+ require "active_support/dependencies"
6
+ require "active_support/descendants_tracker"
7
+ require "active_support/time"
8
+ require "active_support/core_ext/module/attribute_accessors"
9
+ require "active_support/core_ext/array/extract_options"
10
+ require "active_support/core_ext/hash/deep_merge"
11
+ require "active_support/core_ext/hash/slice"
12
+ require "active_support/core_ext/string/behavior"
13
+ require "active_support/core_ext/kernel/singleton_class"
14
+ require "active_support/core_ext/module/introspection"
15
+ require "active_support/core_ext/object/duplicable"
16
+ require "active_support/core_ext/class/subclasses"
17
+ require "active_record/attribute_decorators"
18
+ require "active_record/define_callbacks"
19
+ require "active_record/errors"
20
+ require "active_record/log_subscriber"
21
+ require "active_record/explain_subscriber"
22
+ require "active_record/relation/delegation"
23
+ require "active_record/attributes"
24
+ require "active_record/type_caster"
25
+ require "active_record/database_configurations"
23
26
 
24
27
  module ActiveRecord #:nodoc:
25
28
  # = Active Record
@@ -285,7 +288,7 @@ module ActiveRecord #:nodoc:
285
288
  extend Explain
286
289
  extend Enum
287
290
  extend Delegation::DelegateCache
288
- extend CollectionCacheKey
291
+ extend Aggregations::ClassMethods
289
292
 
290
293
  include Core
291
294
  include Persistence
@@ -303,6 +306,7 @@ module ActiveRecord #:nodoc:
303
306
  include AttributeDecorators
304
307
  include Locking::Optimistic
305
308
  include Locking::Pessimistic
309
+ include DefineCallbacks
306
310
  include AttributeMethods
307
311
  include Callbacks
308
312
  include Timestamp
@@ -310,7 +314,6 @@ module ActiveRecord #:nodoc:
310
314
  include ActiveModel::SecurePassword
311
315
  include AutosaveAssociation
312
316
  include NestedAttributes
313
- include Aggregations
314
317
  include Transactions
315
318
  include TouchLater
316
319
  include NoTouching