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,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
82
+ if options[:inverse_of] && loaded?
83
+ args_flatten = args.flatten
84
+ model = scope.klass
132
85
 
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
144
-
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,43 +232,13 @@ 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?
238
+ target.empty? && !scope.exists?
349
239
  end
350
240
  end
351
241
 
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)
378
- end
379
- end
380
- alias uniq distinct
381
-
382
242
  # Replace this collection with +other_array+. This will perform a diff
383
243
  # and delete/add only records that have changed.
384
244
  def replace(other_array)
@@ -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
 
@@ -487,6 +332,13 @@ module ActiveRecord
487
332
  persisted + memory
488
333
  end
489
334
 
335
+ def build_record(attributes)
336
+ previous = klass.current_scope(true) if block_given?
337
+ super
338
+ ensure
339
+ klass.current_scope = previous if previous
340
+ end
341
+
490
342
  def _create_record(attributes, raise = false, &block)
491
343
  unless owner.persisted?
492
344
  raise ActiveRecord::RecordNotSaved, "You cannot call create unless the parent is saved"
@@ -495,12 +347,17 @@ module ActiveRecord
495
347
  if attributes.is_a?(Array)
496
348
  attributes.collect { |attr| _create_record(attr, raise, &block) }
497
349
  else
350
+ record = build_record(attributes, &block)
498
351
  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? }
352
+ result = nil
353
+ add_to_target(record) do
354
+ result = insert_record(record, true, raise) {
355
+ @_was_loaded = loaded?
356
+ }
502
357
  end
358
+ raise ActiveRecord::Rollback unless result
503
359
  end
360
+ record
504
361
  end
505
362
  end
506
363
 
@@ -513,11 +370,9 @@ module ActiveRecord
513
370
  end
514
371
  end
515
372
 
516
- def create_scope
517
- scope.scope_for_create.stringify_keys
518
- end
519
-
520
373
  def delete_or_destroy(records, method)
374
+ return if records.empty?
375
+ records = find(records) if records.any? { |record| record.kind_of?(Integer) || record.kind_of?(String) }
521
376
  records = records.flatten
522
377
  records.each { |record| raise_on_type_mismatch!(record) }
523
378
  existing_records = records.reject(&:new_record?)
@@ -530,24 +385,28 @@ module ActiveRecord
530
385
  end
531
386
 
532
387
  def remove_records(existing_records, records, method)
533
- records.each { |record| callback(:before_remove, record) }
388
+ catch(:abort) do
389
+ records.each { |record| callback(:before_remove, record) }
390
+ end || return
534
391
 
535
392
  delete_records(existing_records, method) if existing_records.any?
536
- records.each { |record| target.delete(record) }
393
+ @target -= records
394
+ @association_ids = nil
537
395
 
538
396
  records.each { |record| callback(:after_remove, record) }
539
397
  end
540
398
 
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).
399
+ # Delete the given records from the association,
400
+ # using one of the methods +:destroy+, +:delete_all+
401
+ # or +:nullify+ (or +nil+, in which case a default is used).
543
402
  def delete_records(records, method)
544
403
  raise NotImplementedError
545
404
  end
546
405
 
547
406
  def replace_records(new_target, original_target)
548
- delete(target - new_target)
407
+ delete(difference(target, new_target))
549
408
 
550
- unless concat(new_target - target)
409
+ unless concat(difference(new_target, target))
551
410
  @target = original_target
552
411
  raise RecordNotSaved, "Failed to replace #{reflection.name} because one or more of the " \
553
412
  "new records could not be saved."
@@ -557,7 +416,7 @@ module ActiveRecord
557
416
  end
558
417
 
559
418
  def replace_common_records_in_memory(new_target, original_target)
560
- common_records = new_target & original_target
419
+ common_records = intersection(new_target, original_target)
561
420
  common_records.each do |record|
562
421
  skip_callbacks = true
563
422
  replace_on_target(record, @target.index(record), skip_callbacks)
@@ -570,15 +429,23 @@ module ActiveRecord
570
429
  records.each do |record|
571
430
  raise_on_type_mismatch!(record)
572
431
  add_to_target(record) do
573
- result &&= insert_record(record, true, raise) { @_was_loaded = loaded? } unless owner.new_record?
432
+ unless owner.new_record?
433
+ result &&= insert_record(record, true, raise) {
434
+ @_was_loaded = loaded?
435
+ }
436
+ end
574
437
  end
575
438
  end
576
439
 
577
- result && records
440
+ raise ActiveRecord::Rollback unless result
441
+
442
+ records
578
443
  end
579
444
 
580
445
  def replace_on_target(record, index, skip_callbacks)
581
- callback(:before_add, record) unless skip_callbacks
446
+ catch(:abort) do
447
+ callback(:before_add, record)
448
+ end || return unless skip_callbacks
582
449
 
583
450
  set_inverse_instance(record)
584
451
 
@@ -589,6 +456,7 @@ module ActiveRecord
589
456
  if index
590
457
  target[index] = record
591
458
  elsif @_was_loaded || !loaded?
459
+ @association_ids = nil
592
460
  target << record
593
461
  end
594
462
 
@@ -610,25 +478,6 @@ module ActiveRecord
610
478
  owner.class.send(full_callback_name)
611
479
  end
612
480
 
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
481
  def include_in_memory?(record)
633
482
  if reflection.is_a?(ActiveRecord::Reflection::ThroughReflection)
634
483
  assoc = owner.association(reflection.through_reflection.name)
@@ -655,16 +504,6 @@ module ActiveRecord
655
504
  load_target.select { |r| ids.include?(r.id.to_s) }
656
505
  end
657
506
  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
507
  end
669
508
  end
670
509
  end