activerecord 5.2.4.4 → 6.0.3.4

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 (292) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +777 -552
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +5 -3
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record.rb +10 -2
  7. data/lib/active_record/advisory_lock_base.rb +18 -0
  8. data/lib/active_record/aggregations.rb +4 -3
  9. data/lib/active_record/association_relation.rb +10 -8
  10. data/lib/active_record/associations.rb +21 -16
  11. data/lib/active_record/associations/alias_tracker.rb +0 -1
  12. data/lib/active_record/associations/association.rb +56 -19
  13. data/lib/active_record/associations/association_scope.rb +4 -6
  14. data/lib/active_record/associations/belongs_to_association.rb +36 -42
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
  16. data/lib/active_record/associations/builder/association.rb +14 -18
  17. data/lib/active_record/associations/builder/belongs_to.rb +19 -52
  18. data/lib/active_record/associations/builder/collection_association.rb +3 -13
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -40
  20. data/lib/active_record/associations/builder/has_many.rb +2 -0
  21. data/lib/active_record/associations/builder/has_one.rb +35 -1
  22. data/lib/active_record/associations/builder/singular_association.rb +2 -0
  23. data/lib/active_record/associations/collection_association.rb +12 -23
  24. data/lib/active_record/associations/collection_proxy.rb +13 -17
  25. data/lib/active_record/associations/foreign_association.rb +7 -0
  26. data/lib/active_record/associations/has_many_association.rb +2 -11
  27. data/lib/active_record/associations/has_many_through_association.rb +14 -14
  28. data/lib/active_record/associations/has_one_association.rb +28 -30
  29. data/lib/active_record/associations/has_one_through_association.rb +5 -5
  30. data/lib/active_record/associations/join_dependency.rb +37 -28
  31. data/lib/active_record/associations/join_dependency/join_association.rb +9 -10
  32. data/lib/active_record/associations/join_dependency/join_part.rb +2 -2
  33. data/lib/active_record/associations/preloader.rb +39 -32
  34. data/lib/active_record/associations/preloader/association.rb +38 -36
  35. data/lib/active_record/associations/preloader/through_association.rb +48 -39
  36. data/lib/active_record/associations/singular_association.rb +2 -16
  37. data/lib/active_record/attribute_assignment.rb +7 -11
  38. data/lib/active_record/attribute_decorators.rb +0 -2
  39. data/lib/active_record/attribute_methods.rb +28 -100
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +4 -2
  41. data/lib/active_record/attribute_methods/dirty.rb +111 -40
  42. data/lib/active_record/attribute_methods/primary_key.rb +15 -24
  43. data/lib/active_record/attribute_methods/query.rb +2 -3
  44. data/lib/active_record/attribute_methods/read.rb +15 -54
  45. data/lib/active_record/attribute_methods/serialization.rb +1 -2
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -3
  47. data/lib/active_record/attribute_methods/write.rb +17 -25
  48. data/lib/active_record/attributes.rb +13 -1
  49. data/lib/active_record/autosave_association.rb +3 -5
  50. data/lib/active_record/base.rb +2 -3
  51. data/lib/active_record/callbacks.rb +6 -21
  52. data/lib/active_record/coders/yaml_column.rb +0 -1
  53. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +103 -18
  54. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
  55. data/lib/active_record/connection_adapters/abstract/database_statements.rb +102 -124
  56. data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -9
  57. data/lib/active_record/connection_adapters/abstract/quoting.rb +68 -17
  58. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +20 -14
  59. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +100 -72
  60. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
  61. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +175 -79
  62. data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -57
  63. data/lib/active_record/connection_adapters/abstract_adapter.rb +191 -43
  64. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +142 -215
  65. data/lib/active_record/connection_adapters/column.rb +17 -13
  66. data/lib/active_record/connection_adapters/connection_specification.rb +54 -45
  67. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
  68. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  69. data/lib/active_record/connection_adapters/mysql/database_statements.rb +70 -14
  70. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +0 -1
  71. data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
  72. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +4 -6
  73. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
  74. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
  75. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +132 -16
  76. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
  77. data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -10
  78. data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
  79. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +26 -1
  80. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
  81. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  82. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  83. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
  84. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -2
  85. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  86. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  91. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +5 -3
  92. data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
  93. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
  94. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -3
  95. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
  96. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  97. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +63 -75
  98. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
  99. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  100. data/lib/active_record/connection_adapters/postgresql_adapter.rb +168 -75
  101. data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
  102. data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
  103. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
  104. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
  105. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -12
  106. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +135 -146
  107. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  108. data/lib/active_record/connection_handling.rb +139 -26
  109. data/lib/active_record/core.rb +103 -61
  110. data/lib/active_record/counter_cache.rb +8 -30
  111. data/lib/active_record/database_configurations.rb +233 -0
  112. data/lib/active_record/database_configurations/database_config.rb +37 -0
  113. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  114. data/lib/active_record/database_configurations/url_config.rb +78 -0
  115. data/lib/active_record/dynamic_matchers.rb +3 -4
  116. data/lib/active_record/enum.rb +37 -7
  117. data/lib/active_record/errors.rb +15 -7
  118. data/lib/active_record/explain.rb +1 -2
  119. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  120. data/lib/active_record/fixture_set/render_context.rb +17 -0
  121. data/lib/active_record/fixture_set/table_row.rb +152 -0
  122. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  123. data/lib/active_record/fixtures.rb +144 -474
  124. data/lib/active_record/gem_version.rb +3 -3
  125. data/lib/active_record/inheritance.rb +13 -6
  126. data/lib/active_record/insert_all.rb +179 -0
  127. data/lib/active_record/integration.rb +68 -16
  128. data/lib/active_record/internal_metadata.rb +11 -3
  129. data/lib/active_record/locking/optimistic.rb +5 -7
  130. data/lib/active_record/locking/pessimistic.rb +3 -3
  131. data/lib/active_record/log_subscriber.rb +8 -27
  132. data/lib/active_record/middleware/database_selector.rb +74 -0
  133. data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
  134. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  135. data/lib/active_record/migration.rb +104 -85
  136. data/lib/active_record/migration/command_recorder.rb +54 -22
  137. data/lib/active_record/migration/compatibility.rb +79 -52
  138. data/lib/active_record/migration/join_table.rb +0 -1
  139. data/lib/active_record/model_schema.rb +33 -11
  140. data/lib/active_record/nested_attributes.rb +2 -4
  141. data/lib/active_record/no_touching.rb +9 -2
  142. data/lib/active_record/null_relation.rb +0 -1
  143. data/lib/active_record/persistence.rb +232 -29
  144. data/lib/active_record/query_cache.rb +11 -4
  145. data/lib/active_record/querying.rb +33 -21
  146. data/lib/active_record/railtie.rb +80 -43
  147. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  148. data/lib/active_record/railties/controller_runtime.rb +30 -35
  149. data/lib/active_record/railties/databases.rake +199 -46
  150. data/lib/active_record/reflection.rb +40 -38
  151. data/lib/active_record/relation.rb +322 -80
  152. data/lib/active_record/relation/batches.rb +13 -11
  153. data/lib/active_record/relation/calculations.rb +54 -48
  154. data/lib/active_record/relation/delegation.rb +33 -49
  155. data/lib/active_record/relation/finder_methods.rb +23 -28
  156. data/lib/active_record/relation/from_clause.rb +4 -0
  157. data/lib/active_record/relation/merger.rb +11 -21
  158. data/lib/active_record/relation/predicate_builder.rb +5 -11
  159. data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
  160. data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
  161. data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
  162. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  163. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
  164. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  165. data/lib/active_record/relation/query_attribute.rb +13 -8
  166. data/lib/active_record/relation/query_methods.rb +221 -70
  167. data/lib/active_record/relation/spawn_methods.rb +1 -2
  168. data/lib/active_record/relation/where_clause.rb +14 -11
  169. data/lib/active_record/relation/where_clause_factory.rb +1 -2
  170. data/lib/active_record/result.rb +30 -12
  171. data/lib/active_record/sanitization.rb +32 -40
  172. data/lib/active_record/schema.rb +2 -11
  173. data/lib/active_record/schema_dumper.rb +22 -7
  174. data/lib/active_record/schema_migration.rb +6 -2
  175. data/lib/active_record/scoping.rb +8 -9
  176. data/lib/active_record/scoping/default.rb +4 -6
  177. data/lib/active_record/scoping/named.rb +21 -17
  178. data/lib/active_record/statement_cache.rb +30 -3
  179. data/lib/active_record/store.rb +87 -8
  180. data/lib/active_record/suppressor.rb +2 -2
  181. data/lib/active_record/table_metadata.rb +23 -15
  182. data/lib/active_record/tasks/database_tasks.rb +194 -25
  183. data/lib/active_record/tasks/mysql_database_tasks.rb +5 -6
  184. data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -8
  185. data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -9
  186. data/lib/active_record/test_databases.rb +23 -0
  187. data/lib/active_record/test_fixtures.rb +225 -0
  188. data/lib/active_record/timestamp.rb +39 -26
  189. data/lib/active_record/touch_later.rb +5 -4
  190. data/lib/active_record/transactions.rb +64 -73
  191. data/lib/active_record/translation.rb +1 -1
  192. data/lib/active_record/type.rb +3 -5
  193. data/lib/active_record/type/adapter_specific_registry.rb +3 -13
  194. data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
  195. data/lib/active_record/type/serialized.rb +0 -1
  196. data/lib/active_record/type/type_map.rb +0 -1
  197. data/lib/active_record/type/unsigned_integer.rb +0 -1
  198. data/lib/active_record/type_caster/connection.rb +15 -14
  199. data/lib/active_record/type_caster/map.rb +1 -4
  200. data/lib/active_record/validations.rb +3 -3
  201. data/lib/active_record/validations/associated.rb +1 -2
  202. data/lib/active_record/validations/uniqueness.rb +15 -27
  203. data/lib/arel.rb +62 -0
  204. data/lib/arel/alias_predication.rb +9 -0
  205. data/lib/arel/attributes.rb +22 -0
  206. data/lib/arel/attributes/attribute.rb +37 -0
  207. data/lib/arel/collectors/bind.rb +24 -0
  208. data/lib/arel/collectors/composite.rb +31 -0
  209. data/lib/arel/collectors/plain_string.rb +20 -0
  210. data/lib/arel/collectors/sql_string.rb +20 -0
  211. data/lib/arel/collectors/substitute_binds.rb +28 -0
  212. data/lib/arel/crud.rb +42 -0
  213. data/lib/arel/delete_manager.rb +18 -0
  214. data/lib/arel/errors.rb +9 -0
  215. data/lib/arel/expressions.rb +29 -0
  216. data/lib/arel/factory_methods.rb +49 -0
  217. data/lib/arel/insert_manager.rb +49 -0
  218. data/lib/arel/math.rb +45 -0
  219. data/lib/arel/nodes.rb +68 -0
  220. data/lib/arel/nodes/and.rb +32 -0
  221. data/lib/arel/nodes/ascending.rb +23 -0
  222. data/lib/arel/nodes/binary.rb +52 -0
  223. data/lib/arel/nodes/bind_param.rb +36 -0
  224. data/lib/arel/nodes/case.rb +55 -0
  225. data/lib/arel/nodes/casted.rb +50 -0
  226. data/lib/arel/nodes/comment.rb +29 -0
  227. data/lib/arel/nodes/count.rb +12 -0
  228. data/lib/arel/nodes/delete_statement.rb +45 -0
  229. data/lib/arel/nodes/descending.rb +23 -0
  230. data/lib/arel/nodes/equality.rb +18 -0
  231. data/lib/arel/nodes/extract.rb +24 -0
  232. data/lib/arel/nodes/false.rb +16 -0
  233. data/lib/arel/nodes/full_outer_join.rb +8 -0
  234. data/lib/arel/nodes/function.rb +44 -0
  235. data/lib/arel/nodes/grouping.rb +8 -0
  236. data/lib/arel/nodes/in.rb +8 -0
  237. data/lib/arel/nodes/infix_operation.rb +80 -0
  238. data/lib/arel/nodes/inner_join.rb +8 -0
  239. data/lib/arel/nodes/insert_statement.rb +37 -0
  240. data/lib/arel/nodes/join_source.rb +20 -0
  241. data/lib/arel/nodes/matches.rb +18 -0
  242. data/lib/arel/nodes/named_function.rb +23 -0
  243. data/lib/arel/nodes/node.rb +50 -0
  244. data/lib/arel/nodes/node_expression.rb +13 -0
  245. data/lib/arel/nodes/outer_join.rb +8 -0
  246. data/lib/arel/nodes/over.rb +15 -0
  247. data/lib/arel/nodes/regexp.rb +16 -0
  248. data/lib/arel/nodes/right_outer_join.rb +8 -0
  249. data/lib/arel/nodes/select_core.rb +67 -0
  250. data/lib/arel/nodes/select_statement.rb +41 -0
  251. data/lib/arel/nodes/sql_literal.rb +16 -0
  252. data/lib/arel/nodes/string_join.rb +11 -0
  253. data/lib/arel/nodes/table_alias.rb +27 -0
  254. data/lib/arel/nodes/terminal.rb +16 -0
  255. data/lib/arel/nodes/true.rb +16 -0
  256. data/lib/arel/nodes/unary.rb +45 -0
  257. data/lib/arel/nodes/unary_operation.rb +20 -0
  258. data/lib/arel/nodes/unqualified_column.rb +22 -0
  259. data/lib/arel/nodes/update_statement.rb +41 -0
  260. data/lib/arel/nodes/values_list.rb +9 -0
  261. data/lib/arel/nodes/window.rb +126 -0
  262. data/lib/arel/nodes/with.rb +11 -0
  263. data/lib/arel/order_predications.rb +13 -0
  264. data/lib/arel/predications.rb +256 -0
  265. data/lib/arel/select_manager.rb +271 -0
  266. data/lib/arel/table.rb +110 -0
  267. data/lib/arel/tree_manager.rb +72 -0
  268. data/lib/arel/update_manager.rb +34 -0
  269. data/lib/arel/visitors.rb +20 -0
  270. data/lib/arel/visitors/depth_first.rb +203 -0
  271. data/lib/arel/visitors/dot.rb +296 -0
  272. data/lib/arel/visitors/ibm_db.rb +34 -0
  273. data/lib/arel/visitors/informix.rb +62 -0
  274. data/lib/arel/visitors/mssql.rb +156 -0
  275. data/lib/arel/visitors/mysql.rb +83 -0
  276. data/lib/arel/visitors/oracle.rb +158 -0
  277. data/lib/arel/visitors/oracle12.rb +65 -0
  278. data/lib/arel/visitors/postgresql.rb +109 -0
  279. data/lib/arel/visitors/sqlite.rb +38 -0
  280. data/lib/arel/visitors/to_sql.rb +888 -0
  281. data/lib/arel/visitors/visitor.rb +45 -0
  282. data/lib/arel/visitors/where_sql.rb +22 -0
  283. data/lib/arel/window_predications.rb +9 -0
  284. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  285. data/lib/rails/generators/active_record/migration.rb +14 -2
  286. data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
  287. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
  288. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
  289. data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
  290. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  291. metadata +115 -29
  292. data/lib/active_record/collection_cache_key.rb +0 -53
@@ -1,4 +1,6 @@
1
- Copyright (c) 2004-2018 David Heinemeier Hansson
1
+ Copyright (c) 2004-2019 David Heinemeier Hansson
2
+
3
+ Arel originally copyright (c) 2007-2016 Nick Kallen, Bryan Helmkamp, Emilio Tagua, Aaron Patterson
2
4
 
3
5
  Permission is hereby granted, free of charge, to any person obtaining
4
6
  a copy of this software and associated documentation files (the
@@ -13,6 +13,8 @@ columns. Although these mappings can be defined explicitly, it's recommended
13
13
  to follow naming conventions, especially when getting started with the
14
14
  library.
15
15
 
16
+ You can read more about Active Record in the {Active Record Basics}[https://edgeguides.rubyonrails.org/active_record_basics.html] guide.
17
+
16
18
  A short rundown of some of the major features:
17
19
 
18
20
  * Automated mapping between classes and tables, attributes and columns.
@@ -192,7 +194,7 @@ The latest version of Active Record can be installed with RubyGems:
192
194
 
193
195
  Source code can be downloaded as part of the Rails project on GitHub:
194
196
 
195
- * https://github.com/rails/rails/tree/5-2-stable/activerecord
197
+ * https://github.com/rails/rails/tree/master/activerecord
196
198
 
197
199
 
198
200
  == License
@@ -206,7 +208,7 @@ Active Record is released under the MIT license:
206
208
 
207
209
  API documentation is at:
208
210
 
209
- * http://api.rubyonrails.org
211
+ * https://api.rubyonrails.org
210
212
 
211
213
  Bug reports for the Ruby on Rails project can be filed here:
212
214
 
@@ -214,4 +216,4 @@ Bug reports for the Ruby on Rails project can be filed here:
214
216
 
215
217
  Feature requests should be discussed on the rails-core mailing list here:
216
218
 
217
- * https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core
219
+ * https://discuss.rubyonrails.org/c/rubyonrails-core
@@ -176,7 +176,7 @@ Benchmark.ips(TIME) do |x|
176
176
  end
177
177
 
178
178
  x.report "Model.log" do
179
- Exhibit.connection.send(:log, "hello", "world") {}
179
+ Exhibit.connection.send(:log, "hello", "world") { }
180
180
  end
181
181
 
182
182
  x.report "AR.execute(query)" do
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # Copyright (c) 2004-2018 David Heinemeier Hansson
4
+ # Copyright (c) 2004-2019 David Heinemeier Hansson
5
5
  #
6
6
  # Permission is hereby granted, free of charge, to any person obtaining
7
7
  # a copy of this software and associated documentation files (the
@@ -35,6 +35,7 @@ require "active_model/attribute_set"
35
35
  module ActiveRecord
36
36
  extend ActiveSupport::Autoload
37
37
 
38
+ autoload :AdvisoryLockBase
38
39
  autoload :Base
39
40
  autoload :Callbacks
40
41
  autoload :Core
@@ -55,7 +56,6 @@ module ActiveRecord
55
56
  autoload :Persistence
56
57
  autoload :QueryCache
57
58
  autoload :Querying
58
- autoload :CollectionCacheKey
59
59
  autoload :ReadonlyAttributes
60
60
  autoload :RecordInvalid, "active_record/validations"
61
61
  autoload :Reflection
@@ -74,6 +74,7 @@ module ActiveRecord
74
74
  autoload :Translation
75
75
  autoload :Validations
76
76
  autoload :SecureToken
77
+ autoload :DatabaseSelector, "active_record/middleware/database_selector"
77
78
 
78
79
  eager_autoload do
79
80
  autoload :ActiveRecordError, "active_record/errors"
@@ -153,6 +154,12 @@ module ActiveRecord
153
154
  end
154
155
  end
155
156
 
157
+ module Middleware
158
+ extend ActiveSupport::Autoload
159
+
160
+ autoload :DatabaseSelector, "active_record/middleware/database_selector"
161
+ end
162
+
156
163
  module Tasks
157
164
  extend ActiveSupport::Autoload
158
165
 
@@ -163,6 +170,7 @@ module ActiveRecord
163
170
  "active_record/tasks/postgresql_database_tasks"
164
171
  end
165
172
 
173
+ autoload :TestDatabases, "active_record/test_databases"
166
174
  autoload :TestFixtures, "active_record/fixtures"
167
175
 
168
176
  def self.eager_load!
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ # This class is used to create a connection that we can use for advisory
5
+ # locks. This will take out a "global" lock that can't be accidentally
6
+ # removed if a new connection is established during a migration.
7
+ class AdvisoryLockBase < ActiveRecord::Base # :nodoc:
8
+ self.abstract_class = true
9
+
10
+ self.connection_specification_name = "AdvisoryLockBase"
11
+
12
+ class << self
13
+ def _internal?
14
+ true
15
+ end
16
+ end
17
+ end
18
+ end
@@ -3,8 +3,6 @@
3
3
  module ActiveRecord
4
4
  # See ActiveRecord::Aggregations::ClassMethods for documentation
5
5
  module Aggregations
6
- extend ActiveSupport::Concern
7
-
8
6
  def initialize_dup(*) # :nodoc:
9
7
  @aggregation_cache = {}
10
8
  super
@@ -16,7 +14,6 @@ module ActiveRecord
16
14
  end
17
15
 
18
16
  private
19
-
20
17
  def clear_aggregation_cache
21
18
  @aggregation_cache.clear if persisted?
22
19
  end
@@ -225,6 +222,10 @@ module ActiveRecord
225
222
  def composed_of(part_id, options = {})
226
223
  options.assert_valid_keys(:class_name, :mapping, :allow_nil, :constructor, :converter)
227
224
 
225
+ unless self < Aggregations
226
+ include Aggregations
227
+ end
228
+
228
229
  name = part_id.id2name
229
230
  class_name = options[:class_name] || name.camelize
230
231
  mapping = options[:mapping] || [ name, name ]
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ActiveRecord
4
4
  class AssociationRelation < Relation
5
- def initialize(klass, association)
5
+ def initialize(klass, association, **)
6
6
  super(klass)
7
7
  @association = association
8
8
  end
@@ -15,21 +15,23 @@ module ActiveRecord
15
15
  other == records
16
16
  end
17
17
 
18
- def build(*args, &block)
19
- scoping { @association.build(*args, &block) }
18
+ def build(attributes = nil, &block)
19
+ block = _deprecated_scope_block("new", &block)
20
+ scoping { @association.build(attributes, &block) }
20
21
  end
21
22
  alias new build
22
23
 
23
- def create(*args, &block)
24
- scoping { @association.create(*args, &block) }
24
+ def create(attributes = nil, &block)
25
+ block = _deprecated_scope_block("create", &block)
26
+ scoping { @association.create(attributes, &block) }
25
27
  end
26
28
 
27
- def create!(*args, &block)
28
- scoping { @association.create!(*args, &block) }
29
+ def create!(attributes = nil, &block)
30
+ block = _deprecated_scope_block("create!", &block)
31
+ scoping { @association.create!(attributes, &block) }
29
32
  end
30
33
 
31
34
  private
32
-
33
35
  def exec_queries
34
36
  super do |record|
35
37
  @association.set_inverse_instance_from_queries(record)
@@ -92,7 +92,7 @@ module ActiveRecord
92
92
  through_reflection = reflection.through_reflection
93
93
  source_reflection_names = reflection.source_reflection_names
94
94
  source_associations = reflection.through_reflection.klass._reflections.keys
95
- super("Could not find the source association(s) #{source_reflection_names.collect(&:inspect).to_sentence(two_words_connector: ' or ', last_word_connector: ', or ', locale: :en)} in model #{through_reflection.klass}. Try 'has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}, :source => <name>'. Is it one of #{source_associations.to_sentence(two_words_connector: ' or ', last_word_connector: ', or ', locale: :en)}?")
95
+ super("Could not find the source association(s) #{source_reflection_names.collect(&:inspect).to_sentence(two_words_connector: ' or ', last_word_connector: ', or ')} in model #{through_reflection.klass}. Try 'has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}, :source => <name>'. Is it one of #{source_associations.to_sentence(two_words_connector: ' or ', last_word_connector: ', or ')}?")
96
96
  else
97
97
  super("Could not find the source association(s).")
98
98
  end
@@ -292,13 +292,13 @@ module ActiveRecord
292
292
  #
293
293
  # The project class now has the following methods (and more) to ease the traversal and
294
294
  # manipulation of its relationships:
295
- # * <tt>Project#portfolio, Project#portfolio=(portfolio), Project#portfolio.nil?</tt>
296
- # * <tt>Project#project_manager, Project#project_manager=(project_manager), Project#project_manager.nil?,</tt>
297
- # * <tt>Project#milestones.empty?, Project#milestones.size, Project#milestones, Project#milestones<<(milestone),</tt>
298
- # <tt>Project#milestones.delete(milestone), Project#milestones.destroy(milestone), Project#milestones.find(milestone_id),</tt>
299
- # <tt>Project#milestones.build, Project#milestones.create</tt>
300
- # * <tt>Project#categories.empty?, Project#categories.size, Project#categories, Project#categories<<(category1),</tt>
301
- # <tt>Project#categories.delete(category1), Project#categories.destroy(category1)</tt>
295
+ # * <tt>Project#portfolio</tt>, <tt>Project#portfolio=(portfolio)</tt>, <tt>Project#reload_portfolio</tt>
296
+ # * <tt>Project#project_manager</tt>, <tt>Project#project_manager=(project_manager)</tt>, <tt>Project#reload_project_manager</tt>
297
+ # * <tt>Project#milestones.empty?</tt>, <tt>Project#milestones.size</tt>, <tt>Project#milestones</tt>, <tt>Project#milestones<<(milestone)</tt>,
298
+ # <tt>Project#milestones.delete(milestone)</tt>, <tt>Project#milestones.destroy(milestone)</tt>, <tt>Project#milestones.find(milestone_id)</tt>,
299
+ # <tt>Project#milestones.build</tt>, <tt>Project#milestones.create</tt>
300
+ # * <tt>Project#categories.empty?</tt>, <tt>Project#categories.size</tt>, <tt>Project#categories</tt>, <tt>Project#categories<<(category1)</tt>,
301
+ # <tt>Project#categories.delete(category1)</tt>, <tt>Project#categories.destroy(category1)</tt>
302
302
  #
303
303
  # === A word of warning
304
304
  #
@@ -703,8 +703,9 @@ module ActiveRecord
703
703
  # #belongs_to associations.
704
704
  #
705
705
  # Extra options on the associations, as defined in the
706
- # <tt>AssociationReflection::INVALID_AUTOMATIC_INVERSE_OPTIONS</tt> constant, will
707
- # also prevent the association's inverse from being found automatically.
706
+ # <tt>AssociationReflection::INVALID_AUTOMATIC_INVERSE_OPTIONS</tt>
707
+ # constant, or a custom scope, will also prevent the association's inverse
708
+ # from being found automatically.
708
709
  #
709
710
  # The automatic guessing of the inverse association uses a heuristic based
710
711
  # on the name of the class, so it may not work for all associations,
@@ -1293,8 +1294,9 @@ module ActiveRecord
1293
1294
  #
1294
1295
  # * <tt>:destroy</tt> causes all the associated objects to also be destroyed.
1295
1296
  # * <tt>:delete_all</tt> causes all the associated objects to be deleted directly from the database (so callbacks will not be executed).
1296
- # * <tt>:nullify</tt> causes the foreign keys to be set to +NULL+. Callbacks are not executed.
1297
- # * <tt>:restrict_with_exception</tt> causes an exception to be raised if there are any associated records.
1297
+ # * <tt>:nullify</tt> causes the foreign keys to be set to +NULL+. Polymorphic type will also be nullified
1298
+ # on polymorphic associations. Callbacks are not executed.
1299
+ # * <tt>:restrict_with_exception</tt> causes an <tt>ActiveRecord::DeleteRestrictionError</tt> exception to be raised if there are any associated records.
1298
1300
  # * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there are any associated objects.
1299
1301
  #
1300
1302
  # If using with the <tt>:through</tt> option, the association on the join model must be
@@ -1436,8 +1438,9 @@ module ActiveRecord
1436
1438
  #
1437
1439
  # * <tt>:destroy</tt> causes the associated object to also be destroyed
1438
1440
  # * <tt>:delete</tt> causes the associated object to be deleted directly from the database (so callbacks will not execute)
1439
- # * <tt>:nullify</tt> causes the foreign key to be set to +NULL+. Callbacks are not executed.
1440
- # * <tt>:restrict_with_exception</tt> causes an exception to be raised if there is an associated record
1441
+ # * <tt>:nullify</tt> causes the foreign key to be set to +NULL+. Polymorphic type column is also nullified
1442
+ # on polymorphic associations. Callbacks are not executed.
1443
+ # * <tt>:restrict_with_exception</tt> causes an <tt>ActiveRecord::DeleteRestrictionError</tt> exception to be raised if there is an associated record
1441
1444
  # * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there is an associated object
1442
1445
  #
1443
1446
  # Note that <tt>:dependent</tt> option is ignored when using <tt>:through</tt> option.
@@ -1524,6 +1527,7 @@ module ActiveRecord
1524
1527
  # Returns the associated object. +nil+ is returned if none is found.
1525
1528
  # [association=(associate)]
1526
1529
  # Assigns the associate object, extracts the primary key, and sets it as the foreign key.
1530
+ # No modification or deletion of existing records takes place.
1527
1531
  # [build_association(attributes = {})]
1528
1532
  # Returns a new object of the associated type that has been instantiated
1529
1533
  # with +attributes+ and linked to this object through a foreign key, but has not yet been saved.
@@ -1581,7 +1585,7 @@ module ActiveRecord
1581
1585
  # association will use "taggable_type" as the default <tt>:foreign_type</tt>.
1582
1586
  # [:primary_key]
1583
1587
  # Specify the method that returns the primary key of associated object used for the association.
1584
- # By default this is id.
1588
+ # By default this is +id+.
1585
1589
  # [:dependent]
1586
1590
  # If set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to
1587
1591
  # <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method.
@@ -1761,6 +1765,7 @@ module ActiveRecord
1761
1765
  # has_and_belongs_to_many :projects, -> { includes(:milestones, :manager) }
1762
1766
  # has_and_belongs_to_many :categories, ->(post) {
1763
1767
  # where("default_category = ?", post.default_category)
1768
+ # }
1764
1769
  #
1765
1770
  # === Extensions
1766
1771
  #
@@ -1852,7 +1857,7 @@ module ActiveRecord
1852
1857
  hm_options[k] = options[k] if options.key? k
1853
1858
  end
1854
1859
 
1855
- has_many name, scope, hm_options, &extension
1860
+ has_many name, scope, **hm_options, &extension
1856
1861
  _reflections[name.to_s].parent_reflection = habtm_reflection
1857
1862
  end
1858
1863
  end
@@ -72,7 +72,6 @@ module ActiveRecord
72
72
  attr_reader :aliases
73
73
 
74
74
  private
75
-
76
75
  def truncate(name)
77
76
  name.slice(0, @connection.table_alias_length - 2)
78
77
  end
@@ -17,6 +17,23 @@ module ActiveRecord
17
17
  # CollectionAssociation
18
18
  # HasManyAssociation + ForeignAssociation
19
19
  # HasManyThroughAssociation + ThroughAssociation
20
+ #
21
+ # Associations in Active Record are middlemen between the object that
22
+ # holds the association, known as the <tt>owner</tt>, and the associated
23
+ # result set, known as the <tt>target</tt>. Association metadata is available in
24
+ # <tt>reflection</tt>, which is an instance of <tt>ActiveRecord::Reflection::AssociationReflection</tt>.
25
+ #
26
+ # For example, given
27
+ #
28
+ # class Blog < ActiveRecord::Base
29
+ # has_many :posts
30
+ # end
31
+ #
32
+ # blog = Blog.first
33
+ #
34
+ # The association of <tt>blog.posts</tt> has the object +blog+ as its
35
+ # <tt>owner</tt>, the collection of its posts as <tt>target</tt>, and
36
+ # the <tt>reflection</tt> object represents a <tt>:has_many</tt> macro.
20
37
  class Association #:nodoc:
21
38
  attr_reader :owner, :target, :reflection
22
39
 
@@ -40,7 +57,9 @@ module ActiveRecord
40
57
  end
41
58
 
42
59
  # Reloads the \target and returns +self+ on success.
43
- def reload
60
+ # The QueryCache is cleared if +force+ is true.
61
+ def reload(force = false)
62
+ klass.connection.clear_query_cache if force && klass
44
63
  reset
45
64
  reset_scope
46
65
  load_target
@@ -76,18 +95,10 @@ module ActiveRecord
76
95
  end
77
96
 
78
97
  def scope
79
- target_scope.merge!(association_scope)
80
- end
81
-
82
- # The scope for this association.
83
- #
84
- # Note that the association_scope is merged into the target_scope only when the
85
- # scope method is called. This is because at that point the call may be surrounded
86
- # by scope.scoping { ... } or with_scope { ... } etc, which affects the scope which
87
- # actually gets built.
88
- def association_scope
89
- if klass
90
- @association_scope ||= AssociationScope.scope(self)
98
+ if (scope = klass.current_scope) && scope.try(:proxy_association) == self
99
+ scope.spawn
100
+ else
101
+ target_scope.merge!(association_scope)
91
102
  end
92
103
  end
93
104
 
@@ -129,12 +140,6 @@ module ActiveRecord
129
140
  reflection.klass
130
141
  end
131
142
 
132
- # Can be overridden (i.e. in ThroughAssociation) to merge in other scopes (i.e. the
133
- # through association's scope)
134
- def target_scope
135
- AssociationRelation.create(klass, self).merge!(klass.all)
136
- end
137
-
138
143
  def extensions
139
144
  extensions = klass.default_extensions | reflection.extensions
140
145
 
@@ -195,6 +200,38 @@ module ActiveRecord
195
200
  end
196
201
 
197
202
  private
203
+ def find_target
204
+ scope = self.scope
205
+ return scope.to_a if skip_statement_cache?(scope)
206
+
207
+ conn = klass.connection
208
+ sc = reflection.association_scope_cache(conn, owner) do |params|
209
+ as = AssociationScope.create { params.bind }
210
+ target_scope.merge!(as.scope(self))
211
+ end
212
+
213
+ binds = AssociationScope.get_bind_values(owner, reflection.chain)
214
+ sc.execute(binds, conn) { |record| set_inverse_instance(record) } || []
215
+ end
216
+
217
+ # The scope for this association.
218
+ #
219
+ # Note that the association_scope is merged into the target_scope only when the
220
+ # scope method is called. This is because at that point the call may be surrounded
221
+ # by scope.scoping { ... } or unscoped { ... } etc, which affects the scope which
222
+ # actually gets built.
223
+ def association_scope
224
+ if klass
225
+ @association_scope ||= AssociationScope.scope(self)
226
+ end
227
+ end
228
+
229
+ # Can be overridden (i.e. in ThroughAssociation) to merge in other scopes (i.e. the
230
+ # through association's scope)
231
+ def target_scope
232
+ AssociationRelation.create(klass, self).merge!(klass.scope_for_association)
233
+ end
234
+
198
235
  def scope_for_create
199
236
  scope.scope_for_create
200
237
  end
@@ -26,7 +26,9 @@ module ActiveRecord
26
26
  chain = get_chain(reflection, association, scope.alias_tracker)
27
27
 
28
28
  scope.extending! reflection.extensions
29
- add_constraints(scope, owner, chain)
29
+ scope = add_constraints(scope, owner, chain)
30
+ scope.limit!(1) unless reflection.collection?
31
+ scope
30
32
  end
31
33
 
32
34
  def self.get_bind_values(owner, chain)
@@ -46,13 +48,9 @@ module ActiveRecord
46
48
  binds
47
49
  end
48
50
 
49
- # TODO Change this to private once we've dropped Ruby 2.2 support.
50
- # Workaround for Ruby 2.2 "private attribute?" warning.
51
- protected
52
-
51
+ private
53
52
  attr_reader :value_transformation
54
53
 
55
- private
56
54
  def join(table, constraint)
57
55
  table.create_join(table, table.create_on(constraint))
58
56
  end
@@ -16,21 +16,6 @@ module ActiveRecord
16
16
  end
17
17
  end
18
18
 
19
- def replace(record)
20
- if record
21
- raise_on_type_mismatch!(record)
22
- update_counters_on_replace(record)
23
- set_inverse_instance(record)
24
- @updated = true
25
- else
26
- decrement_counters
27
- end
28
-
29
- replace_keys(record)
30
-
31
- self.target = record
32
- end
33
-
34
19
  def inversed_from(record)
35
20
  replace_keys(record)
36
21
  super
@@ -49,30 +34,60 @@ module ActiveRecord
49
34
  @updated
50
35
  end
51
36
 
52
- def decrement_counters # :nodoc:
37
+ def decrement_counters
53
38
  update_counters(-1)
54
39
  end
55
40
 
56
- def increment_counters # :nodoc:
41
+ def increment_counters
57
42
  update_counters(1)
58
43
  end
59
44
 
45
+ def decrement_counters_before_last_save
46
+ if reflection.polymorphic?
47
+ model_was = owner.attribute_before_last_save(reflection.foreign_type).try(:constantize)
48
+ else
49
+ model_was = klass
50
+ end
51
+
52
+ foreign_key_was = owner.attribute_before_last_save(reflection.foreign_key)
53
+
54
+ if foreign_key_was && model_was < ActiveRecord::Base
55
+ update_counters_via_scope(model_was, foreign_key_was, -1)
56
+ end
57
+ end
58
+
60
59
  def target_changed?
61
60
  owner.saved_change_to_attribute?(reflection.foreign_key)
62
61
  end
63
62
 
64
63
  private
64
+ def replace(record)
65
+ if record
66
+ raise_on_type_mismatch!(record)
67
+ set_inverse_instance(record)
68
+ @updated = true
69
+ end
70
+
71
+ replace_keys(record)
72
+
73
+ self.target = record
74
+ end
65
75
 
66
76
  def update_counters(by)
67
77
  if require_counter_update? && foreign_key_present?
68
78
  if target && !stale_target?
69
79
  target.increment!(reflection.counter_cache_column, by, touch: reflection.options[:touch])
70
80
  else
71
- klass.update_counters(target_id, reflection.counter_cache_column => by, touch: reflection.options[:touch])
81
+ update_counters_via_scope(klass, owner._read_attribute(reflection.foreign_key), by)
72
82
  end
73
83
  end
74
84
  end
75
85
 
86
+ def update_counters_via_scope(klass, foreign_key, by)
87
+ scope = klass.unscoped.where!(primary_key(klass) => foreign_key)
88
+ scope.update_counters(reflection.counter_cache_column => by, touch: reflection.options[:touch])
89
+ end
90
+
76
91
  def find_target?
77
92
  !loaded? && foreign_key_present? && klass
78
93
  end
@@ -81,25 +96,12 @@ module ActiveRecord
81
96
  reflection.counter_cache_column && owner.persisted?
82
97
  end
83
98
 
84
- def update_counters_on_replace(record)
85
- if require_counter_update? && different_target?(record)
86
- owner.instance_variable_set :@_after_replace_counter_called, true
87
- record.increment!(reflection.counter_cache_column, touch: reflection.options[:touch])
88
- decrement_counters
89
- end
90
- end
91
-
92
- # Checks whether record is different to the current target, without loading it
93
- def different_target?(record)
94
- record._read_attribute(primary_key(record)) != owner._read_attribute(reflection.foreign_key)
95
- end
96
-
97
99
  def replace_keys(record)
98
- owner[reflection.foreign_key] = record ? record._read_attribute(primary_key(record)) : nil
100
+ owner[reflection.foreign_key] = record ? record._read_attribute(primary_key(record.class)) : nil
99
101
  end
100
102
 
101
- def primary_key(record)
102
- reflection.association_primary_key(record.class)
103
+ def primary_key(klass)
104
+ reflection.association_primary_key(klass)
103
105
  end
104
106
 
105
107
  def foreign_key_present?
@@ -113,14 +115,6 @@ module ActiveRecord
113
115
  inverse && inverse.has_one?
114
116
  end
115
117
 
116
- def target_id
117
- if options[:primary_key]
118
- owner.send(reflection.name).try(:id)
119
- else
120
- owner._read_attribute(reflection.foreign_key)
121
- end
122
- end
123
-
124
118
  def stale_state
125
119
  result = owner._read_attribute(reflection.foreign_key) { |n| owner.send(:missing_attribute, n, caller) }
126
120
  result && result.to_s