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,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This class is inherited by the has_one and belongs_to association classes
2
4
 
3
5
  module ActiveRecord::Associations::Builder # :nodoc:
@@ -36,5 +38,7 @@ module ActiveRecord::Associations::Builder # :nodoc:
36
38
  end
37
39
  CODE
38
40
  end
41
+
42
+ private_class_method :valid_options, :define_accessors, :define_constructors
39
43
  end
40
44
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Associations
3
5
  # = Active Record Association Collection
@@ -10,9 +12,9 @@ module ActiveRecord
10
12
  # HasManyAssociation => has_many
11
13
  # HasManyThroughAssociation + ThroughAssociation => has_many :through
12
14
  #
13
- # CollectionAssociation class provides common methods to the collections
15
+ # The CollectionAssociation class provides common methods to the collections
14
16
  # defined by +has_and_belongs_to_many+, +has_many+ or +has_many+ with
15
- # +:through association+ option.
17
+ # the +:through association+ option.
16
18
  #
17
19
  # You need to be careful with assumptions regarding the target: The proxy
18
20
  # does not fetch records from the database until it needs them, but new
@@ -24,18 +26,9 @@ module ActiveRecord
24
26
  # If you need to work on all current children, new and existing records,
25
27
  # +load_target+ and the +loaded+ flag are your friends.
26
28
  class CollectionAssociation < Association #:nodoc:
27
-
28
29
  # Implements the reader method, e.g. foo.items for Foo.has_many :items
29
- def reader(force_reload = false)
30
- if force_reload
31
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
32
- Passing an argument to force an association to reload is now
33
- deprecated and will be removed in Rails 5.1. Please call `reload`
34
- on the result collection proxy instead.
35
- MSG
36
-
37
- klass.uncached { reload }
38
- elsif stale_target?
30
+ def reader
31
+ if stale_target?
39
32
  reload
40
33
  end
41
34
 
@@ -51,30 +44,29 @@ module ActiveRecord
51
44
  # Implements the ids reader method, e.g. foo.item_ids for Foo.has_many :items
52
45
  def ids_reader
53
46
  if loaded?
54
- load_target.map do |record|
55
- record.send(reflection.association_primary_key)
56
- end
47
+ target.pluck(reflection.association_primary_key)
48
+ elsif !target.empty?
49
+ load_target.pluck(reflection.association_primary_key)
57
50
  else
58
- @association_ids ||= (
59
- column = "#{reflection.quoted_table_name}.#{reflection.association_primary_key}"
60
- scope.pluck(column)
61
- )
51
+ @association_ids ||= scope.pluck(reflection.association_primary_key)
62
52
  end
63
53
  end
64
54
 
65
55
  # Implements the ids writer method, e.g. foo.item_ids= for Foo.has_many :items
66
56
  def ids_writer(ids)
67
- pk_type = reflection.association_primary_key_type
57
+ primary_key = reflection.association_primary_key
58
+ pk_type = klass.type_for_attribute(primary_key)
68
59
  ids = Array(ids).reject(&:blank?)
69
60
  ids.map! { |i| pk_type.cast(i) }
70
61
 
71
- primary_key = reflection.association_primary_key
72
62
  records = klass.where(primary_key => ids).index_by do |r|
73
63
  r.public_send(primary_key)
74
64
  end.values_at(*ids).compact
75
65
 
76
66
  if records.size != ids.size
77
- klass.all.raise_record_not_found_exception!(ids, records.size, ids.size, primary_key)
67
+ found_ids = records.map { |record| record.public_send(primary_key) }
68
+ not_found_ids = ids - found_ids
69
+ klass.all.raise_record_not_found_exception!(ids, records.size, ids.size, primary_key, not_found_ids)
78
70
  else
79
71
  replace(records)
80
72
  end
@@ -83,80 +75,29 @@ module ActiveRecord
83
75
  def reset
84
76
  super
85
77
  @target = []
86
- end
87
-
88
- def select(*fields)
89
- if block_given?
90
- load_target.select.each { |e| yield e }
91
- else
92
- scope.select(*fields)
93
- end
78
+ @association_ids = nil
94
79
  end
95
80
 
96
81
  def find(*args)
97
- if block_given?
98
- load_target.find(*args) { |*block_args| yield(*block_args) }
99
- else
100
- if options[:inverse_of] && loaded?
101
- args_flatten = args.flatten
102
- raise RecordNotFound, "Couldn't find #{scope.klass.name} without an ID" if args_flatten.blank?
103
- result = find_by_scan(*args)
104
-
105
- result_size = Array(result).size
106
- if !result || result_size != args_flatten.size
107
- scope.raise_record_not_found_exception!(args_flatten, result_size, args_flatten.size)
108
- else
109
- result
110
- end
111
- else
112
- scope.find(*args)
113
- end
114
- end
115
- end
116
-
117
- def first(*args)
118
- first_nth_or_last(:first, *args)
119
- end
120
-
121
- def second(*args)
122
- first_nth_or_last(:second, *args)
123
- end
124
-
125
- def third(*args)
126
- first_nth_or_last(:third, *args)
127
- end
128
-
129
- def fourth(*args)
130
- first_nth_or_last(:fourth, *args)
131
- end
132
-
133
- def fifth(*args)
134
- first_nth_or_last(:fifth, *args)
135
- end
136
-
137
- def forty_two(*args)
138
- first_nth_or_last(:forty_two, *args)
139
- end
140
-
141
- def third_to_last(*args)
142
- first_nth_or_last(:third_to_last, *args)
143
- end
82
+ if options[:inverse_of] && loaded?
83
+ args_flatten = args.flatten
84
+ model = scope.klass
144
85
 
145
- def second_to_last(*args)
146
- first_nth_or_last(:second_to_last, *args)
147
- end
86
+ if args_flatten.blank?
87
+ error_message = "Couldn't find #{model.name} without an ID"
88
+ raise RecordNotFound.new(error_message, model.name, model.primary_key, args)
89
+ end
148
90
 
149
- def last(*args)
150
- first_nth_or_last(:last, *args)
151
- end
91
+ result = find_by_scan(*args)
152
92
 
153
- def take(n = nil)
154
- if loaded?
155
- n ? target.take(n) : target.first
156
- else
157
- scope.take(n).tap do |record|
158
- set_inverse_instance record if record.is_a? ActiveRecord::Base
93
+ result_size = Array(result).size
94
+ if !result || result_size != args_flatten.size
95
+ scope.raise_record_not_found_exception!(args_flatten, result_size, args_flatten.size)
96
+ else
97
+ result
159
98
  end
99
+ else
100
+ scope.find(*args)
160
101
  end
161
102
  end
162
103
 
@@ -164,23 +105,12 @@ module ActiveRecord
164
105
  if attributes.is_a?(Array)
165
106
  attributes.collect { |attr| build(attr, &block) }
166
107
  else
167
- add_to_target(build_record(attributes)) do |record|
168
- yield(record) if block_given?
169
- end
108
+ add_to_target(build_record(attributes, &block))
170
109
  end
171
110
  end
172
111
 
173
- def create(attributes = {}, &block)
174
- _create_record(attributes, &block)
175
- end
176
-
177
- def create!(attributes = {}, &block)
178
- _create_record(attributes, true, &block)
179
- end
180
-
181
- # Add +records+ to this association. Returns +self+ so method calls may
182
- # be chained. Since << flattens its argument list and inserts each record,
183
- # +push+ and +concat+ behave identically.
112
+ # Add +records+ to this association. Since +<<+ flattens its argument list
113
+ # and inserts each record, +push+ and +concat+ behave identically.
184
114
  def concat(*records)
185
115
  records = records.flatten
186
116
  if owner.new_record?
@@ -225,12 +155,12 @@ module ActiveRecord
225
155
  end
226
156
 
227
157
  dependent = if dependent
228
- dependent
229
- elsif options[:dependent] == :destroy
230
- :delete_all
231
- else
232
- options[:dependent]
233
- end
158
+ dependent
159
+ elsif options[:dependent] == :destroy
160
+ :delete_all
161
+ else
162
+ options[:dependent]
163
+ end
234
164
 
235
165
  delete_or_nullify_all_records(dependent).tap do
236
166
  reset
@@ -248,28 +178,6 @@ module ActiveRecord
248
178
  end
249
179
  end
250
180
 
251
- # Count all records using SQL. Construct options and pass them with
252
- # scope to the target class's +count+.
253
- def count(column_name = nil)
254
- relation = scope
255
- if association_scope.distinct_value
256
- # This is needed because 'SELECT count(DISTINCT *)..' is not valid SQL.
257
- column_name ||= reflection.klass.primary_key
258
- relation = relation.distinct
259
- end
260
-
261
- value = relation.count(column_name)
262
-
263
- limit = options[:limit]
264
- offset = options[:offset]
265
-
266
- if limit || offset
267
- [ [value - offset.to_i, 0].max, limit.to_i ].min
268
- else
269
- value
270
- end
271
- end
272
-
273
181
  # Removes +records+ from this association calling +before_remove+ and
274
182
  # +after_remove+ callbacks.
275
183
  #
@@ -278,12 +186,7 @@ module ActiveRecord
278
186
  # are actually removed from the database, that depends precisely on
279
187
  # +delete_records+. They are in any case removed from the collection.
280
188
  def delete(*records)
281
- return if records.empty?
282
- _options = records.extract_options!
283
- dependent = _options[:dependent] || options[:dependent]
284
-
285
- records = find(records) if records.any? { |record| record.kind_of?(Integer) || record.kind_of?(String) }
286
- delete_or_destroy(records, dependent)
189
+ delete_or_destroy(records, options[:dependent])
287
190
  end
288
191
 
289
192
  # Deletes the +records+ and removes them from this association calling
@@ -292,8 +195,6 @@ module ActiveRecord
292
195
  # Note that this method removes records from the database ignoring the
293
196
  # +:dependent+ option.
294
197
  def destroy(*records)
295
- return if records.empty?
296
- records = find(records) if records.any? { |record| record.kind_of?(Integer) || record.kind_of?(String) }
297
198
  delete_or_destroy(records, :destroy)
298
199
  end
299
200
 
@@ -309,14 +210,12 @@ module ActiveRecord
309
210
  # +count_records+, which is a method descendants have to provide.
310
211
  def size
311
212
  if !find_target? || loaded?
312
- if association_scope.distinct_value
313
- target.uniq.size
314
- else
315
- target.size
316
- end
213
+ target.size
214
+ elsif @association_ids
215
+ @association_ids.size
317
216
  elsif !association_scope.group_values.empty?
318
217
  load_target.size
319
- elsif !association_scope.distinct_value && target.is_a?(Array)
218
+ elsif !association_scope.distinct_value && !target.empty?
320
219
  unsaved_records = target.select(&:new_record?)
321
220
  unsaved_records.size + count_records
322
221
  else
@@ -324,15 +223,6 @@ module ActiveRecord
324
223
  end
325
224
  end
326
225
 
327
- # Returns the size of the collection calling +size+ on the target.
328
- #
329
- # If the collection has been already loaded +length+ and +size+ are
330
- # equivalent. If not and you are going to need the records anyway this
331
- # method will take one less query. Otherwise +size+ is more efficient.
332
- def length
333
- load_target.size
334
- end
335
-
336
226
  # Returns true if the collection is empty.
337
227
  #
338
228
  # If the collection has been loaded
@@ -342,42 +232,12 @@ module ActiveRecord
342
232
  # loaded and you are going to fetch the records anyway it is better to
343
233
  # check <tt>collection.length.zero?</tt>.
344
234
  def empty?
345
- if loaded?
235
+ if loaded? || @association_ids || reflection.has_cached_counter?
346
236
  size.zero?
347
237
  else
348
- @target.blank? && !scope.exists?
349
- end
350
- end
351
-
352
- # Returns true if the collections is not empty.
353
- # If block given, loads all records and checks for one or more matches.
354
- # Otherwise, equivalent to +!collection.empty?+.
355
- def any?
356
- if block_given?
357
- load_target.any? { |*block_args| yield(*block_args) }
358
- else
359
- !empty?
360
- end
361
- end
362
-
363
- # Returns true if the collection has more than 1 record.
364
- # If block given, loads all records and checks for two or more matches.
365
- # Otherwise, equivalent to +collection.size > 1+.
366
- def many?
367
- if block_given?
368
- load_target.many? { |*block_args| yield(*block_args) }
369
- else
370
- size > 1
371
- end
372
- end
373
-
374
- def distinct
375
- seen = {}
376
- load_target.find_all do |record|
377
- seen[record.id] = true unless seen.key?(record.id)
238
+ target.empty? && !scope.exists?
378
239
  end
379
240
  end
380
- alias uniq distinct
381
241
 
382
242
  # Replace this collection with +other_array+. This will perform a diff
383
243
  # and delete/add only records that have changed.
@@ -435,28 +295,13 @@ module ActiveRecord
435
295
  owner.new_record? && !foreign_key_present?
436
296
  end
437
297
 
438
- private
439
- def get_records(&block)
440
- return scope.to_a if skip_statement_cache?
441
-
442
- conn = klass.connection
443
- sc = reflection.association_scope_cache(conn, owner) do
444
- StatementCache.create(conn) { |params|
445
- as = AssociationScope.create { params.bind }
446
- target_scope.merge as.scope(self, conn)
447
- }
448
- end
449
-
450
- binds = AssociationScope.get_bind_values(owner, reflection.chain)
451
- sc.execute(binds, klass, klass.connection, &block)
298
+ def find_from_target?
299
+ loaded? ||
300
+ owner.new_record? ||
301
+ target.any? { |record| record.new_record? || record.changed? }
452
302
  end
453
303
 
454
- def find_target
455
- get_records do |record|
456
- set_inverse_instance(record)
457
- end
458
- end
459
-
304
+ private
460
305
  # We have some records loaded from the database (persisted) and some that are
461
306
  # in-memory (memory). The same record may be represented in the persisted array
462
307
  # and in the memory array.
@@ -474,7 +319,7 @@ module ActiveRecord
474
319
  persisted.map! do |record|
475
320
  if mem_record = memory.delete(record)
476
321
 
477
- ((record.attribute_names & mem_record.attribute_names) - mem_record.changes.keys).each do |name|
322
+ ((record.attribute_names & mem_record.attribute_names) - mem_record.changed_attribute_names_to_save).each do |name|
478
323
  mem_record[name] = record[name]
479
324
  end
480
325
 
@@ -495,12 +340,17 @@ module ActiveRecord
495
340
  if attributes.is_a?(Array)
496
341
  attributes.collect { |attr| _create_record(attr, raise, &block) }
497
342
  else
343
+ record = build_record(attributes, &block)
498
344
  transaction do
499
- add_to_target(build_record(attributes)) do |record|
500
- yield(record) if block_given?
501
- insert_record(record, true, raise) { @_was_loaded = loaded? }
345
+ result = nil
346
+ add_to_target(record) do
347
+ result = insert_record(record, true, raise) {
348
+ @_was_loaded = loaded?
349
+ }
502
350
  end
351
+ raise ActiveRecord::Rollback unless result
503
352
  end
353
+ record
504
354
  end
505
355
  end
506
356
 
@@ -513,11 +363,9 @@ module ActiveRecord
513
363
  end
514
364
  end
515
365
 
516
- def create_scope
517
- scope.scope_for_create.stringify_keys
518
- end
519
-
520
366
  def delete_or_destroy(records, method)
367
+ return if records.empty?
368
+ records = find(records) if records.any? { |record| record.kind_of?(Integer) || record.kind_of?(String) }
521
369
  records = records.flatten
522
370
  records.each { |record| raise_on_type_mismatch!(record) }
523
371
  existing_records = records.reject(&:new_record?)
@@ -533,21 +381,23 @@ module ActiveRecord
533
381
  records.each { |record| callback(:before_remove, record) }
534
382
 
535
383
  delete_records(existing_records, method) if existing_records.any?
536
- records.each { |record| target.delete(record) }
384
+ @target -= records
385
+ @association_ids = nil
537
386
 
538
387
  records.each { |record| callback(:after_remove, record) }
539
388
  end
540
389
 
541
- # Delete the given records from the association, using one of the methods :destroy,
542
- # :delete_all or :nullify (or nil, in which case a default is used).
390
+ # Delete the given records from the association,
391
+ # using one of the methods +:destroy+, +:delete_all+
392
+ # or +:nullify+ (or +nil+, in which case a default is used).
543
393
  def delete_records(records, method)
544
394
  raise NotImplementedError
545
395
  end
546
396
 
547
397
  def replace_records(new_target, original_target)
548
- delete(target - new_target)
398
+ delete(difference(target, new_target))
549
399
 
550
- unless concat(new_target - target)
400
+ unless concat(difference(new_target, target))
551
401
  @target = original_target
552
402
  raise RecordNotSaved, "Failed to replace #{reflection.name} because one or more of the " \
553
403
  "new records could not be saved."
@@ -557,7 +407,7 @@ module ActiveRecord
557
407
  end
558
408
 
559
409
  def replace_common_records_in_memory(new_target, original_target)
560
- common_records = new_target & original_target
410
+ common_records = intersection(new_target, original_target)
561
411
  common_records.each do |record|
562
412
  skip_callbacks = true
563
413
  replace_on_target(record, @target.index(record), skip_callbacks)
@@ -570,11 +420,17 @@ module ActiveRecord
570
420
  records.each do |record|
571
421
  raise_on_type_mismatch!(record)
572
422
  add_to_target(record) do
573
- result &&= insert_record(record, true, raise) { @_was_loaded = loaded? } unless owner.new_record?
423
+ unless owner.new_record?
424
+ result &&= insert_record(record, true, raise) {
425
+ @_was_loaded = loaded?
426
+ }
427
+ end
574
428
  end
575
429
  end
576
430
 
577
- result && records
431
+ raise ActiveRecord::Rollback unless result
432
+
433
+ records
578
434
  end
579
435
 
580
436
  def replace_on_target(record, index, skip_callbacks)
@@ -589,6 +445,7 @@ module ActiveRecord
589
445
  if index
590
446
  target[index] = record
591
447
  elsif @_was_loaded || !loaded?
448
+ @association_ids = nil
592
449
  target << record
593
450
  end
594
451
 
@@ -610,25 +467,6 @@ module ActiveRecord
610
467
  owner.class.send(full_callback_name)
611
468
  end
612
469
 
613
- # Should we deal with assoc.first or assoc.last by issuing an independent query to
614
- # the database, or by getting the target, and then taking the first/last item from that?
615
- #
616
- # If the args is just a non-empty options hash, go to the database.
617
- #
618
- # Otherwise, go to the database only if none of the following are true:
619
- # * target already loaded
620
- # * owner is new record
621
- # * target contains new or changed record(s)
622
- def fetch_first_nth_or_last_using_find?(args)
623
- if args.first.is_a?(Hash)
624
- true
625
- else
626
- !(loaded? ||
627
- owner.new_record? ||
628
- target.any? { |record| record.new_record? || record.changed? })
629
- end
630
- end
631
-
632
470
  def include_in_memory?(record)
633
471
  if reflection.is_a?(ActiveRecord::Reflection::ThroughReflection)
634
472
  assoc = owner.association(reflection.through_reflection.name)
@@ -655,16 +493,6 @@ module ActiveRecord
655
493
  load_target.select { |r| ids.include?(r.id.to_s) }
656
494
  end
657
495
  end
658
-
659
- # Fetches the first/last using SQL if possible, otherwise from the target array.
660
- def first_nth_or_last(type, *args)
661
- args.shift if args.first.is_a?(Hash) && args.first.empty?
662
-
663
- collection = fetch_first_nth_or_last_using_find?(args) ? scope : load_target
664
- collection.send(type, *args).tap do |record|
665
- set_inverse_instance record if record.is_a? ActiveRecord::Base
666
- end
667
- end
668
496
  end
669
497
  end
670
498
  end