activerecord 5.0.7.2 → 6.0.6.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 (359) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +844 -1944
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +9 -7
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record/advisory_lock_base.rb +18 -0
  8. data/lib/active_record/aggregations.rb +249 -247
  9. data/lib/active_record/association_relation.rb +18 -14
  10. data/lib/active_record/associations/alias_tracker.rb +24 -34
  11. data/lib/active_record/associations/association.rb +113 -55
  12. data/lib/active_record/associations/association_scope.rb +102 -96
  13. data/lib/active_record/associations/belongs_to_association.rb +58 -42
  14. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  15. data/lib/active_record/associations/builder/association.rb +18 -25
  16. data/lib/active_record/associations/builder/belongs_to.rb +43 -54
  17. data/lib/active_record/associations/builder/collection_association.rb +7 -18
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +41 -62
  19. data/lib/active_record/associations/builder/has_many.rb +4 -0
  20. data/lib/active_record/associations/builder/has_one.rb +37 -1
  21. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  22. data/lib/active_record/associations/collection_association.rb +93 -254
  23. data/lib/active_record/associations/collection_proxy.rb +159 -122
  24. data/lib/active_record/associations/foreign_association.rb +9 -0
  25. data/lib/active_record/associations/has_many_association.rb +23 -30
  26. data/lib/active_record/associations/has_many_through_association.rb +58 -44
  27. data/lib/active_record/associations/has_one_association.rb +59 -54
  28. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  29. data/lib/active_record/associations/join_dependency/join_association.rb +43 -85
  30. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  31. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  32. data/lib/active_record/associations/join_dependency.rb +152 -177
  33. data/lib/active_record/associations/preloader/association.rb +101 -97
  34. data/lib/active_record/associations/preloader/through_association.rb +77 -76
  35. data/lib/active_record/associations/preloader.rb +94 -103
  36. data/lib/active_record/associations/singular_association.rb +12 -45
  37. data/lib/active_record/associations/through_association.rb +27 -15
  38. data/lib/active_record/associations.rb +1603 -1592
  39. data/lib/active_record/attribute_assignment.rb +54 -61
  40. data/lib/active_record/attribute_decorators.rb +38 -17
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +12 -8
  42. data/lib/active_record/attribute_methods/dirty.rb +179 -109
  43. data/lib/active_record/attribute_methods/primary_key.rb +85 -92
  44. data/lib/active_record/attribute_methods/query.rb +4 -3
  45. data/lib/active_record/attribute_methods/read.rb +20 -49
  46. data/lib/active_record/attribute_methods/serialization.rb +29 -7
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -66
  48. data/lib/active_record/attribute_methods/write.rb +34 -33
  49. data/lib/active_record/attribute_methods.rb +66 -106
  50. data/lib/active_record/attributes.rb +38 -25
  51. data/lib/active_record/autosave_association.rb +58 -39
  52. data/lib/active_record/base.rb +27 -24
  53. data/lib/active_record/callbacks.rb +64 -35
  54. data/lib/active_record/coders/json.rb +2 -0
  55. data/lib/active_record/coders/yaml_column.rb +34 -13
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +558 -323
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +215 -94
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -35
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +128 -75
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -28
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +233 -147
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +400 -213
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -79
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +373 -202
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +401 -562
  69. data/lib/active_record/connection_adapters/column.rb +41 -13
  70. data/lib/active_record/connection_adapters/connection_specification.rb +172 -139
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
  72. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +137 -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 +49 -45
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -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 +12 -13
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +48 -30
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +19 -31
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -54
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +12 -2
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -18
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  97. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  99. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  100. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +30 -9
  101. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -30
  102. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  104. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +8 -4
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  107. data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +20 -26
  110. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  112. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +378 -308
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +383 -275
  117. data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
  118. data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
  119. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +261 -267
  127. data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
  128. data/lib/active_record/connection_handling.rb +143 -40
  129. data/lib/active_record/core.rb +207 -160
  130. data/lib/active_record/counter_cache.rb +60 -28
  131. data/lib/active_record/database_configurations/database_config.rb +37 -0
  132. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  133. data/lib/active_record/database_configurations/url_config.rb +78 -0
  134. data/lib/active_record/database_configurations.rb +233 -0
  135. data/lib/active_record/define_callbacks.rb +22 -0
  136. data/lib/active_record/dynamic_matchers.rb +87 -87
  137. data/lib/active_record/enum.rb +67 -23
  138. data/lib/active_record/errors.rb +114 -18
  139. data/lib/active_record/explain.rb +4 -4
  140. data/lib/active_record/explain_registry.rb +3 -1
  141. data/lib/active_record/explain_subscriber.rb +9 -4
  142. data/lib/active_record/fixture_set/file.rb +13 -8
  143. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  144. data/lib/active_record/fixture_set/render_context.rb +17 -0
  145. data/lib/active_record/fixture_set/table_row.rb +152 -0
  146. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  147. data/lib/active_record/fixtures.rb +194 -504
  148. data/lib/active_record/gem_version.rb +5 -3
  149. data/lib/active_record/inheritance.rb +150 -99
  150. data/lib/active_record/insert_all.rb +179 -0
  151. data/lib/active_record/integration.rb +116 -25
  152. data/lib/active_record/internal_metadata.rb +16 -19
  153. data/lib/active_record/legacy_yaml_adapter.rb +4 -2
  154. data/lib/active_record/locking/optimistic.rb +85 -86
  155. data/lib/active_record/locking/pessimistic.rb +18 -6
  156. data/lib/active_record/log_subscriber.rb +48 -29
  157. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  158. data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
  159. data/lib/active_record/middleware/database_selector.rb +74 -0
  160. data/lib/active_record/migration/command_recorder.rb +134 -100
  161. data/lib/active_record/migration/compatibility.rb +174 -56
  162. data/lib/active_record/migration/join_table.rb +8 -7
  163. data/lib/active_record/migration.rb +369 -302
  164. data/lib/active_record/model_schema.rb +160 -127
  165. data/lib/active_record/nested_attributes.rb +213 -202
  166. data/lib/active_record/no_touching.rb +12 -3
  167. data/lib/active_record/null_relation.rb +12 -34
  168. data/lib/active_record/persistence.rb +446 -77
  169. data/lib/active_record/query_cache.rb +13 -12
  170. data/lib/active_record/querying.rb +37 -24
  171. data/lib/active_record/railtie.rb +128 -36
  172. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  173. data/lib/active_record/railties/console_sandbox.rb +2 -0
  174. data/lib/active_record/railties/controller_runtime.rb +34 -33
  175. data/lib/active_record/railties/databases.rake +312 -177
  176. data/lib/active_record/readonly_attributes.rb +5 -4
  177. data/lib/active_record/reflection.rb +214 -254
  178. data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
  179. data/lib/active_record/relation/batches.rb +98 -52
  180. data/lib/active_record/relation/calculations.rb +212 -173
  181. data/lib/active_record/relation/delegation.rb +73 -69
  182. data/lib/active_record/relation/finder_methods.rb +207 -247
  183. data/lib/active_record/relation/from_clause.rb +6 -8
  184. data/lib/active_record/relation/merger.rb +82 -61
  185. data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
  186. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  187. data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
  188. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  189. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  190. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  191. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  192. data/lib/active_record/relation/predicate_builder.rb +83 -105
  193. data/lib/active_record/relation/query_attribute.rb +33 -2
  194. data/lib/active_record/relation/query_methods.rb +488 -332
  195. data/lib/active_record/relation/record_fetch_warning.rb +5 -3
  196. data/lib/active_record/relation/spawn_methods.rb +8 -8
  197. data/lib/active_record/relation/where_clause.rb +111 -96
  198. data/lib/active_record/relation/where_clause_factory.rb +6 -11
  199. data/lib/active_record/relation.rb +443 -318
  200. data/lib/active_record/result.rb +69 -40
  201. data/lib/active_record/runtime_registry.rb +5 -3
  202. data/lib/active_record/sanitization.rb +83 -99
  203. data/lib/active_record/schema.rb +7 -14
  204. data/lib/active_record/schema_dumper.rb +71 -69
  205. data/lib/active_record/schema_migration.rb +16 -6
  206. data/lib/active_record/scoping/default.rb +92 -95
  207. data/lib/active_record/scoping/named.rb +51 -26
  208. data/lib/active_record/scoping.rb +20 -20
  209. data/lib/active_record/secure_token.rb +4 -2
  210. data/lib/active_record/serialization.rb +2 -0
  211. data/lib/active_record/statement_cache.rb +63 -28
  212. data/lib/active_record/store.rb +121 -41
  213. data/lib/active_record/suppressor.rb +6 -3
  214. data/lib/active_record/table_metadata.rb +39 -18
  215. data/lib/active_record/tasks/database_tasks.rb +271 -81
  216. data/lib/active_record/tasks/mysql_database_tasks.rb +54 -91
  217. data/lib/active_record/tasks/postgresql_database_tasks.rb +77 -47
  218. data/lib/active_record/tasks/sqlite_database_tasks.rb +33 -16
  219. data/lib/active_record/test_databases.rb +23 -0
  220. data/lib/active_record/test_fixtures.rb +243 -0
  221. data/lib/active_record/timestamp.rb +70 -36
  222. data/lib/active_record/touch_later.rb +8 -6
  223. data/lib/active_record/transactions.rb +141 -157
  224. data/lib/active_record/translation.rb +3 -1
  225. data/lib/active_record/type/adapter_specific_registry.rb +44 -48
  226. data/lib/active_record/type/date.rb +2 -0
  227. data/lib/active_record/type/date_time.rb +2 -0
  228. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  229. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  230. data/lib/active_record/type/internal/timezone.rb +2 -0
  231. data/lib/active_record/type/json.rb +30 -0
  232. data/lib/active_record/type/serialized.rb +16 -9
  233. data/lib/active_record/type/text.rb +11 -0
  234. data/lib/active_record/type/time.rb +12 -1
  235. data/lib/active_record/type/type_map.rb +14 -17
  236. data/lib/active_record/type/unsigned_integer.rb +16 -0
  237. data/lib/active_record/type.rb +23 -18
  238. data/lib/active_record/type_caster/connection.rb +17 -12
  239. data/lib/active_record/type_caster/map.rb +5 -4
  240. data/lib/active_record/type_caster.rb +4 -2
  241. data/lib/active_record/validations/absence.rb +2 -0
  242. data/lib/active_record/validations/associated.rb +3 -2
  243. data/lib/active_record/validations/length.rb +2 -0
  244. data/lib/active_record/validations/presence.rb +4 -2
  245. data/lib/active_record/validations/uniqueness.rb +29 -42
  246. data/lib/active_record/validations.rb +7 -5
  247. data/lib/active_record/version.rb +3 -1
  248. data/lib/active_record.rb +37 -22
  249. data/lib/arel/alias_predication.rb +9 -0
  250. data/lib/arel/attributes/attribute.rb +37 -0
  251. data/lib/arel/attributes.rb +22 -0
  252. data/lib/arel/collectors/bind.rb +24 -0
  253. data/lib/arel/collectors/composite.rb +31 -0
  254. data/lib/arel/collectors/plain_string.rb +20 -0
  255. data/lib/arel/collectors/sql_string.rb +20 -0
  256. data/lib/arel/collectors/substitute_binds.rb +28 -0
  257. data/lib/arel/crud.rb +42 -0
  258. data/lib/arel/delete_manager.rb +18 -0
  259. data/lib/arel/errors.rb +9 -0
  260. data/lib/arel/expressions.rb +29 -0
  261. data/lib/arel/factory_methods.rb +49 -0
  262. data/lib/arel/insert_manager.rb +49 -0
  263. data/lib/arel/math.rb +45 -0
  264. data/lib/arel/nodes/and.rb +32 -0
  265. data/lib/arel/nodes/ascending.rb +23 -0
  266. data/lib/arel/nodes/binary.rb +52 -0
  267. data/lib/arel/nodes/bind_param.rb +36 -0
  268. data/lib/arel/nodes/case.rb +55 -0
  269. data/lib/arel/nodes/casted.rb +50 -0
  270. data/lib/arel/nodes/comment.rb +29 -0
  271. data/lib/arel/nodes/count.rb +12 -0
  272. data/lib/arel/nodes/delete_statement.rb +45 -0
  273. data/lib/arel/nodes/descending.rb +23 -0
  274. data/lib/arel/nodes/equality.rb +18 -0
  275. data/lib/arel/nodes/extract.rb +24 -0
  276. data/lib/arel/nodes/false.rb +16 -0
  277. data/lib/arel/nodes/full_outer_join.rb +8 -0
  278. data/lib/arel/nodes/function.rb +44 -0
  279. data/lib/arel/nodes/grouping.rb +8 -0
  280. data/lib/arel/nodes/in.rb +8 -0
  281. data/lib/arel/nodes/infix_operation.rb +80 -0
  282. data/lib/arel/nodes/inner_join.rb +8 -0
  283. data/lib/arel/nodes/insert_statement.rb +37 -0
  284. data/lib/arel/nodes/join_source.rb +20 -0
  285. data/lib/arel/nodes/matches.rb +18 -0
  286. data/lib/arel/nodes/named_function.rb +23 -0
  287. data/lib/arel/nodes/node.rb +50 -0
  288. data/lib/arel/nodes/node_expression.rb +13 -0
  289. data/lib/arel/nodes/outer_join.rb +8 -0
  290. data/lib/arel/nodes/over.rb +15 -0
  291. data/lib/arel/nodes/regexp.rb +16 -0
  292. data/lib/arel/nodes/right_outer_join.rb +8 -0
  293. data/lib/arel/nodes/select_core.rb +67 -0
  294. data/lib/arel/nodes/select_statement.rb +41 -0
  295. data/lib/arel/nodes/sql_literal.rb +16 -0
  296. data/lib/arel/nodes/string_join.rb +11 -0
  297. data/lib/arel/nodes/table_alias.rb +27 -0
  298. data/lib/arel/nodes/terminal.rb +16 -0
  299. data/lib/arel/nodes/true.rb +16 -0
  300. data/lib/arel/nodes/unary.rb +45 -0
  301. data/lib/arel/nodes/unary_operation.rb +20 -0
  302. data/lib/arel/nodes/unqualified_column.rb +22 -0
  303. data/lib/arel/nodes/update_statement.rb +41 -0
  304. data/lib/arel/nodes/values_list.rb +9 -0
  305. data/lib/arel/nodes/window.rb +126 -0
  306. data/lib/arel/nodes/with.rb +11 -0
  307. data/lib/arel/nodes.rb +68 -0
  308. data/lib/arel/order_predications.rb +13 -0
  309. data/lib/arel/predications.rb +256 -0
  310. data/lib/arel/select_manager.rb +271 -0
  311. data/lib/arel/table.rb +110 -0
  312. data/lib/arel/tree_manager.rb +72 -0
  313. data/lib/arel/update_manager.rb +34 -0
  314. data/lib/arel/visitors/depth_first.rb +203 -0
  315. data/lib/arel/visitors/dot.rb +296 -0
  316. data/lib/arel/visitors/ibm_db.rb +34 -0
  317. data/lib/arel/visitors/informix.rb +62 -0
  318. data/lib/arel/visitors/mssql.rb +156 -0
  319. data/lib/arel/visitors/mysql.rb +83 -0
  320. data/lib/arel/visitors/oracle.rb +158 -0
  321. data/lib/arel/visitors/oracle12.rb +65 -0
  322. data/lib/arel/visitors/postgresql.rb +109 -0
  323. data/lib/arel/visitors/sqlite.rb +38 -0
  324. data/lib/arel/visitors/to_sql.rb +888 -0
  325. data/lib/arel/visitors/visitor.rb +45 -0
  326. data/lib/arel/visitors/where_sql.rb +22 -0
  327. data/lib/arel/visitors.rb +20 -0
  328. data/lib/arel/window_predications.rb +9 -0
  329. data/lib/arel.rb +62 -0
  330. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -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 -3
  335. data/lib/rails/generators/active_record/model/model_generator.rb +9 -30
  336. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  337. data/lib/rails/generators/active_record.rb +7 -5
  338. metadata +138 -52
  339. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  340. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  341. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  342. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  343. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  344. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  345. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  346. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  347. data/lib/active_record/attribute.rb +0 -213
  348. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  349. data/lib/active_record/attribute_set/builder.rb +0 -132
  350. data/lib/active_record/attribute_set.rb +0 -110
  351. data/lib/active_record/collection_cache_key.rb +0 -50
  352. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  353. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  354. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  355. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  356. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  357. data/lib/active_record/type/internal/abstract_json.rb +0 -33
  358. /data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  359. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -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
 
@@ -241,25 +255,24 @@ module ActiveRecord
241
255
  end
242
256
 
243
257
  private
258
+ NO_DEFAULT_PROVIDED = Object.new # :nodoc:
259
+ private_constant :NO_DEFAULT_PROVIDED
244
260
 
245
- NO_DEFAULT_PROVIDED = Object.new # :nodoc:
246
- private_constant :NO_DEFAULT_PROVIDED
247
-
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)
261
+ def define_default_attribute(name, value, type, from_user:)
262
+ if value == NO_DEFAULT_PROVIDED
263
+ default_attribute = _default_attributes[name].with_type(type)
264
+ elsif from_user
265
+ default_attribute = ActiveModel::Attribute::UserProvidedDefault.new(
266
+ name,
267
+ value,
268
+ type,
269
+ _default_attributes.fetch(name.to_s) { nil },
270
+ )
271
+ else
272
+ default_attribute = ActiveModel::Attribute.from_database(name, value, type)
273
+ end
274
+ _default_attributes[name] = default_attribute
260
275
  end
261
- _default_attributes[name] = default_attribute
262
- end
263
276
  end
264
277
  end
265
278
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # = Active Record Autosave Association
3
5
  #
@@ -27,7 +29,7 @@ module ActiveRecord
27
29
  # == Callbacks
28
30
  #
29
31
  # Association with autosave option defines several callbacks on your
30
- # model (before_save, after_create, after_update). Please note that
32
+ # model (around_save, before_save, after_create, after_update). Please note that
31
33
  # callbacks are executed in the order they were defined in
32
34
  # model. You should avoid modifying the association content, before
33
35
  # autosave callbacks are executed. Placing your callbacks after
@@ -140,24 +142,22 @@ 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
  def define_non_cyclic_method(name, &block)
151
- return if method_defined?(name)
151
+ return if instance_methods(false).include?(name)
152
152
  define_method(name) do |*args|
153
153
  result = true; @_already_called ||= {}
154
154
  # Loop prevention for validation of associations
155
155
  unless @_already_called[name]
156
156
  begin
157
- @_already_called[name]=true
157
+ @_already_called[name] = true
158
158
  result = instance_eval(&block)
159
159
  ensure
160
- @_already_called[name]=false
160
+ @_already_called[name] = false
161
161
  end
162
162
  end
163
163
 
@@ -180,7 +180,7 @@ module ActiveRecord
180
180
  save_method = :"autosave_associated_records_for_#{reflection.name}"
181
181
 
182
182
  if reflection.collection?
183
- before_save :before_save_collection_association
183
+ around_save :around_save_collection_association
184
184
 
185
185
  define_non_cyclic_method(save_method) { save_collection_association(reflection) }
186
186
  # Doesn't use after_save as that would save associations added in after_create/after_update twice
@@ -215,13 +215,7 @@ module ActiveRecord
215
215
  method = :validate_single_association
216
216
  end
217
217
 
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
218
+ define_non_cyclic_method(validation_method) { send(method, reflection) }
225
219
  validate validation_method
226
220
  after_validation :_ensure_no_duplicate_errors
227
221
  end
@@ -267,16 +261,15 @@ module ActiveRecord
267
261
  # Returns whether or not this record has been changed in any way (including whether
268
262
  # any of its nested autosave associations are likewise changed)
269
263
  def changed_for_autosave?
270
- new_record? || changed? || marked_for_destruction? || nested_records_changed_for_autosave?
264
+ new_record? || has_changes_to_save? || marked_for_destruction? || nested_records_changed_for_autosave?
271
265
  end
272
266
 
273
267
  private
274
-
275
268
  # Returns the record for an association collection that should be validated
276
269
  # or saved. If +autosave+ is +false+ only new records will be returned,
277
270
  # unless the parent is/was a new record itself.
278
271
  def associated_records_to_validate_or_save(association, new_record, autosave)
279
- if new_record
272
+ if new_record || custom_validation_context?
280
273
  association && association.target
281
274
  elsif autosave
282
275
  association.target.find_all(&:changed_for_autosave?)
@@ -308,7 +301,7 @@ module ActiveRecord
308
301
  def validate_single_association(reflection)
309
302
  association = association_instance_get(reflection.name)
310
303
  record = association && association.reader
311
- association_valid?(reflection, record) if record
304
+ association_valid?(reflection, record) if record && (record.changed_for_autosave? || custom_validation_context?)
312
305
  end
313
306
 
314
307
  # Validate the associated records if <tt>:validate</tt> or
@@ -325,12 +318,12 @@ module ActiveRecord
325
318
  # Returns whether or not the association is valid and applies any errors to
326
319
  # the parent, <tt>self</tt>, if it wasn't. Skips any <tt>:autosave</tt>
327
320
  # enabled records if they're marked_for_destruction? or destroyed.
328
- def association_valid?(reflection, record, index=nil)
321
+ def association_valid?(reflection, record, index = nil)
329
322
  return true if record.destroyed? || (reflection.options[:autosave] && record.marked_for_destruction?)
330
323
 
331
- validation_context = self.validation_context unless [:create, :update].include?(self.validation_context)
324
+ context = validation_context if custom_validation_context?
332
325
 
333
- unless valid = record.valid?(validation_context)
326
+ unless valid = record.valid?(context)
334
327
  if reflection.options[:autosave]
335
328
  indexed_attribute = !index.nil? && (reflection.options[:index_errors] || ActiveRecord::Base.index_nested_attribute_errors)
336
329
 
@@ -364,11 +357,15 @@ module ActiveRecord
364
357
  end
365
358
  end
366
359
 
367
- # Is used as a before_save callback to check while saving a collection
360
+ # Is used as an around_save callback to check while saving a collection
368
361
  # association whether or not the parent was a new record before saving.
369
- def before_save_collection_association
370
- @new_record_before_save = new_record?
371
- true
362
+ def around_save_collection_association
363
+ previously_new_record_before_save = (@new_record_before_save ||= false)
364
+ @new_record_before_save = !previously_new_record_before_save && new_record?
365
+
366
+ yield
367
+ ensure
368
+ @new_record_before_save = previously_new_record_before_save
372
369
  end
373
370
 
374
371
  # Saves any new associated records, or all loaded autosave associations if
@@ -383,7 +380,14 @@ module ActiveRecord
383
380
  if association = association_instance_get(reflection.name)
384
381
  autosave = reflection.options[:autosave]
385
382
 
386
- if records = associated_records_to_validate_or_save(association, @new_record_before_save, autosave)
383
+ # By saving the instance variable in a local variable,
384
+ # we make the whole callback re-entrant.
385
+ new_record_before_save = @new_record_before_save
386
+
387
+ # reconstruct the scope now that we know the owner's id
388
+ association.reset_scope
389
+
390
+ if records = associated_records_to_validate_or_save(association, new_record_before_save, autosave)
387
391
  if autosave
388
392
  records_to_destroy = records.select(&:marked_for_destruction?)
389
393
  records_to_destroy.each { |record| association.destroy(record) }
@@ -395,22 +399,24 @@ module ActiveRecord
395
399
 
396
400
  saved = true
397
401
 
398
- if autosave != false && (@new_record_before_save || record.new_record?)
402
+ if autosave != false && (new_record_before_save || record.new_record?)
399
403
  if autosave
400
404
  saved = association.insert_record(record, false)
401
- else
402
- association.insert_record(record) unless reflection.nested?
405
+ elsif !reflection.nested?
406
+ association_saved = association.insert_record(record)
407
+
408
+ if reflection.validate?
409
+ errors.add(reflection.name) unless association_saved
410
+ saved = association_saved
411
+ end
403
412
  end
404
413
  elsif autosave
405
- saved = record.save(:validate => false)
414
+ saved = record.save(validate: false)
406
415
  end
407
416
 
408
- raise ActiveRecord::Rollback unless saved
417
+ raise(RecordInvalid.new(association.owner)) unless saved
409
418
  end
410
419
  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
420
  end
415
421
  end
416
422
 
@@ -437,9 +443,12 @@ module ActiveRecord
437
443
  if (autosave && record.changed_for_autosave?) || new_record? || record_changed?(reflection, record, key)
438
444
  unless reflection.through_reflection
439
445
  record[reflection.foreign_key] = key
446
+ if inverse_reflection = reflection.inverse_of
447
+ record.association(inverse_reflection.name).inversed_from(self)
448
+ end
440
449
  end
441
450
 
442
- saved = record.save(:validate => !autosave)
451
+ saved = record.save(validate: !autosave)
443
452
  raise ActiveRecord::Rollback if !saved && autosave
444
453
  saved
445
454
  end
@@ -450,8 +459,14 @@ module ActiveRecord
450
459
  # If the record is new or it has changed, returns true.
451
460
  def record_changed?(reflection, record, key)
452
461
  record.new_record? ||
453
- (record.has_attribute?(reflection.foreign_key) && record[reflection.foreign_key] != key) ||
454
- record.attribute_changed?(reflection.foreign_key)
462
+ association_foreign_key_changed?(reflection, record, key) ||
463
+ record.will_save_change_to_attribute?(reflection.foreign_key)
464
+ end
465
+
466
+ def association_foreign_key_changed?(reflection, record, key)
467
+ return false if reflection.through_reflection?
468
+
469
+ record.has_attribute?(reflection.foreign_key) && record[reflection.foreign_key] != key
455
470
  end
456
471
 
457
472
  # Saves the associated record if it's new or <tt>:autosave</tt> is enabled.
@@ -469,7 +484,7 @@ module ActiveRecord
469
484
  self[reflection.foreign_key] = nil
470
485
  record.destroy
471
486
  elsif autosave != false
472
- saved = record.save(:validate => !autosave) if record.new_record? || (autosave && record.changed_for_autosave?)
487
+ saved = record.save(validate: !autosave) if record.new_record? || (autosave && record.changed_for_autosave?)
473
488
 
474
489
  if association.updated?
475
490
  association_id = record.send(reflection.options[:primary_key] || :id)
@@ -482,6 +497,10 @@ module ActiveRecord
482
497
  end
483
498
  end
484
499
 
500
+ def custom_validation_context?
501
+ validation_context && [:create, :update].exclude?(validation_context)
502
+ end
503
+
485
504
  def _ensure_no_duplicate_errors
486
505
  errors.messages.each_key do |attribute|
487
506
  errors[attribute].uniq!