activerecord 5.2.3 → 6.1.0

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 (316) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +898 -532
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +7 -5
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/aggregations.rb +5 -4
  7. data/lib/active_record/association_relation.rb +22 -12
  8. data/lib/active_record/associations/alias_tracker.rb +19 -16
  9. data/lib/active_record/associations/association.rb +95 -42
  10. data/lib/active_record/associations/association_scope.rb +21 -21
  11. data/lib/active_record/associations/belongs_to_association.rb +50 -46
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -5
  13. data/lib/active_record/associations/builder/association.rb +23 -21
  14. data/lib/active_record/associations/builder/belongs_to.rb +29 -59
  15. data/lib/active_record/associations/builder/collection_association.rb +10 -19
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -41
  17. data/lib/active_record/associations/builder/has_many.rb +8 -2
  18. data/lib/active_record/associations/builder/has_one.rb +33 -2
  19. data/lib/active_record/associations/builder/singular_association.rb +3 -1
  20. data/lib/active_record/associations/collection_association.rb +31 -29
  21. data/lib/active_record/associations/collection_proxy.rb +25 -21
  22. data/lib/active_record/associations/foreign_association.rb +20 -0
  23. data/lib/active_record/associations/has_many_association.rb +26 -13
  24. data/lib/active_record/associations/has_many_through_association.rb +27 -28
  25. data/lib/active_record/associations/has_one_association.rb +43 -31
  26. data/lib/active_record/associations/has_one_through_association.rb +5 -5
  27. data/lib/active_record/associations/join_dependency/join_association.rb +54 -12
  28. data/lib/active_record/associations/join_dependency/join_part.rb +5 -5
  29. data/lib/active_record/associations/join_dependency.rb +91 -60
  30. data/lib/active_record/associations/preloader/association.rb +71 -43
  31. data/lib/active_record/associations/preloader/through_association.rb +49 -40
  32. data/lib/active_record/associations/preloader.rb +48 -35
  33. data/lib/active_record/associations/singular_association.rb +3 -17
  34. data/lib/active_record/associations/through_association.rb +1 -1
  35. data/lib/active_record/associations.rb +133 -25
  36. data/lib/active_record/attribute_assignment.rb +17 -19
  37. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -7
  38. data/lib/active_record/attribute_methods/dirty.rb +101 -40
  39. data/lib/active_record/attribute_methods/primary_key.rb +20 -25
  40. data/lib/active_record/attribute_methods/query.rb +4 -8
  41. data/lib/active_record/attribute_methods/read.rb +14 -56
  42. data/lib/active_record/attribute_methods/serialization.rb +12 -7
  43. data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
  44. data/lib/active_record/attribute_methods/write.rb +18 -34
  45. data/lib/active_record/attribute_methods.rb +81 -143
  46. data/lib/active_record/attributes.rb +45 -8
  47. data/lib/active_record/autosave_association.rb +76 -47
  48. data/lib/active_record/base.rb +4 -17
  49. data/lib/active_record/callbacks.rb +158 -43
  50. data/lib/active_record/coders/yaml_column.rb +1 -2
  51. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +293 -132
  52. data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -36
  53. data/lib/active_record/connection_adapters/abstract/database_statements.rb +167 -146
  54. data/lib/active_record/connection_adapters/abstract/query_cache.rb +21 -17
  55. data/lib/active_record/connection_adapters/abstract/quoting.rb +98 -47
  56. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  57. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -110
  58. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +203 -90
  59. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -4
  60. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +381 -146
  61. data/lib/active_record/connection_adapters/abstract/transaction.rb +155 -68
  62. data/lib/active_record/connection_adapters/abstract_adapter.rb +229 -98
  63. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +243 -275
  64. data/lib/active_record/connection_adapters/column.rb +30 -12
  65. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  66. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
  67. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  68. data/lib/active_record/connection_adapters/mysql/database_statements.rb +86 -32
  69. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
  70. data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
  71. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +34 -10
  72. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +48 -32
  73. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
  74. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +139 -19
  75. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +14 -9
  76. data/lib/active_record/connection_adapters/mysql2_adapter.rb +53 -18
  77. data/lib/active_record/connection_adapters/pool_config.rb +63 -0
  78. data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
  79. data/lib/active_record/connection_adapters/postgresql/column.rb +37 -28
  80. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +38 -54
  81. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  83. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  84. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
  85. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
  86. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +3 -4
  90. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  92. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
  94. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
  95. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  96. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  97. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
  98. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  99. data/lib/active_record/connection_adapters/postgresql/quoting.rb +47 -10
  100. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
  101. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +19 -4
  102. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
  103. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  104. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +120 -100
  105. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
  106. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  107. data/lib/active_record/connection_adapters/postgresql_adapter.rb +222 -112
  108. data/lib/active_record/connection_adapters/schema_cache.rb +127 -21
  109. data/lib/active_record/connection_adapters/sql_type_metadata.rb +19 -6
  110. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
  111. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
  112. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  113. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +77 -13
  114. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +175 -187
  115. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  116. data/lib/active_record/connection_adapters.rb +50 -0
  117. data/lib/active_record/connection_handling.rb +285 -33
  118. data/lib/active_record/core.rb +308 -100
  119. data/lib/active_record/counter_cache.rb +8 -30
  120. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  121. data/lib/active_record/database_configurations/database_config.rb +80 -0
  122. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  123. data/lib/active_record/database_configurations/url_config.rb +53 -0
  124. data/lib/active_record/database_configurations.rb +272 -0
  125. data/lib/active_record/delegated_type.rb +209 -0
  126. data/lib/active_record/destroy_association_async_job.rb +36 -0
  127. data/lib/active_record/dynamic_matchers.rb +3 -4
  128. data/lib/active_record/enum.rb +71 -17
  129. data/lib/active_record/errors.rb +62 -19
  130. data/lib/active_record/explain.rb +10 -6
  131. data/lib/active_record/explain_subscriber.rb +1 -1
  132. data/lib/active_record/fixture_set/file.rb +10 -17
  133. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  134. data/lib/active_record/fixture_set/render_context.rb +17 -0
  135. data/lib/active_record/fixture_set/table_row.rb +152 -0
  136. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  137. data/lib/active_record/fixtures.rb +197 -481
  138. data/lib/active_record/gem_version.rb +3 -3
  139. data/lib/active_record/inheritance.rb +53 -24
  140. data/lib/active_record/insert_all.rb +208 -0
  141. data/lib/active_record/integration.rb +67 -17
  142. data/lib/active_record/internal_metadata.rb +26 -9
  143. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  144. data/lib/active_record/locking/optimistic.rb +26 -22
  145. data/lib/active_record/locking/pessimistic.rb +9 -5
  146. data/lib/active_record/log_subscriber.rb +34 -35
  147. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  148. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  149. data/lib/active_record/middleware/database_selector.rb +77 -0
  150. data/lib/active_record/migration/command_recorder.rb +96 -44
  151. data/lib/active_record/migration/compatibility.rb +141 -64
  152. data/lib/active_record/migration/join_table.rb +0 -1
  153. data/lib/active_record/migration.rb +205 -156
  154. data/lib/active_record/model_schema.rb +148 -22
  155. data/lib/active_record/nested_attributes.rb +4 -7
  156. data/lib/active_record/no_touching.rb +8 -1
  157. data/lib/active_record/null_relation.rb +0 -1
  158. data/lib/active_record/persistence.rb +267 -59
  159. data/lib/active_record/query_cache.rb +21 -4
  160. data/lib/active_record/querying.rb +40 -23
  161. data/lib/active_record/railtie.rb +115 -58
  162. data/lib/active_record/railties/controller_runtime.rb +30 -35
  163. data/lib/active_record/railties/databases.rake +402 -78
  164. data/lib/active_record/readonly_attributes.rb +4 -0
  165. data/lib/active_record/reflection.rb +113 -101
  166. data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
  167. data/lib/active_record/relation/batches.rb +44 -35
  168. data/lib/active_record/relation/calculations.rb +157 -93
  169. data/lib/active_record/relation/delegation.rb +35 -50
  170. data/lib/active_record/relation/finder_methods.rb +65 -40
  171. data/lib/active_record/relation/from_clause.rb +5 -1
  172. data/lib/active_record/relation/merger.rb +32 -40
  173. data/lib/active_record/relation/predicate_builder/array_handler.rb +13 -13
  174. data/lib/active_record/relation/predicate_builder/association_query_value.rb +5 -9
  175. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  176. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -7
  177. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  178. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  179. data/lib/active_record/relation/predicate_builder.rb +58 -40
  180. data/lib/active_record/relation/query_attribute.rb +13 -8
  181. data/lib/active_record/relation/query_methods.rb +487 -199
  182. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  183. data/lib/active_record/relation/spawn_methods.rb +9 -9
  184. data/lib/active_record/relation/where_clause.rb +108 -58
  185. data/lib/active_record/relation.rb +375 -104
  186. data/lib/active_record/result.rb +64 -38
  187. data/lib/active_record/runtime_registry.rb +2 -2
  188. data/lib/active_record/sanitization.rb +22 -41
  189. data/lib/active_record/schema.rb +2 -11
  190. data/lib/active_record/schema_dumper.rb +54 -9
  191. data/lib/active_record/schema_migration.rb +7 -9
  192. data/lib/active_record/scoping/default.rb +6 -8
  193. data/lib/active_record/scoping/named.rb +17 -24
  194. data/lib/active_record/scoping.rb +8 -9
  195. data/lib/active_record/secure_token.rb +16 -8
  196. data/lib/active_record/serialization.rb +5 -3
  197. data/lib/active_record/signed_id.rb +116 -0
  198. data/lib/active_record/statement_cache.rb +51 -8
  199. data/lib/active_record/store.rb +88 -9
  200. data/lib/active_record/suppressor.rb +2 -2
  201. data/lib/active_record/table_metadata.rb +39 -43
  202. data/lib/active_record/tasks/database_tasks.rb +276 -81
  203. data/lib/active_record/tasks/mysql_database_tasks.rb +37 -39
  204. data/lib/active_record/tasks/postgresql_database_tasks.rb +27 -32
  205. data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -17
  206. data/lib/active_record/test_databases.rb +24 -0
  207. data/lib/active_record/test_fixtures.rb +246 -0
  208. data/lib/active_record/timestamp.rb +43 -32
  209. data/lib/active_record/touch_later.rb +23 -22
  210. data/lib/active_record/transactions.rb +59 -117
  211. data/lib/active_record/translation.rb +1 -1
  212. data/lib/active_record/type/adapter_specific_registry.rb +3 -13
  213. data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
  214. data/lib/active_record/type/serialized.rb +6 -3
  215. data/lib/active_record/type/time.rb +10 -0
  216. data/lib/active_record/type/type_map.rb +0 -1
  217. data/lib/active_record/type/unsigned_integer.rb +0 -1
  218. data/lib/active_record/type.rb +10 -5
  219. data/lib/active_record/type_caster/connection.rb +15 -15
  220. data/lib/active_record/type_caster/map.rb +8 -8
  221. data/lib/active_record/validations/associated.rb +1 -2
  222. data/lib/active_record/validations/numericality.rb +35 -0
  223. data/lib/active_record/validations/uniqueness.rb +38 -30
  224. data/lib/active_record/validations.rb +4 -3
  225. data/lib/active_record.rb +13 -12
  226. data/lib/arel/alias_predication.rb +9 -0
  227. data/lib/arel/attributes/attribute.rb +41 -0
  228. data/lib/arel/collectors/bind.rb +29 -0
  229. data/lib/arel/collectors/composite.rb +39 -0
  230. data/lib/arel/collectors/plain_string.rb +20 -0
  231. data/lib/arel/collectors/sql_string.rb +27 -0
  232. data/lib/arel/collectors/substitute_binds.rb +35 -0
  233. data/lib/arel/crud.rb +42 -0
  234. data/lib/arel/delete_manager.rb +18 -0
  235. data/lib/arel/errors.rb +9 -0
  236. data/lib/arel/expressions.rb +29 -0
  237. data/lib/arel/factory_methods.rb +49 -0
  238. data/lib/arel/insert_manager.rb +49 -0
  239. data/lib/arel/math.rb +45 -0
  240. data/lib/arel/nodes/and.rb +32 -0
  241. data/lib/arel/nodes/ascending.rb +23 -0
  242. data/lib/arel/nodes/binary.rb +126 -0
  243. data/lib/arel/nodes/bind_param.rb +44 -0
  244. data/lib/arel/nodes/case.rb +55 -0
  245. data/lib/arel/nodes/casted.rb +62 -0
  246. data/lib/arel/nodes/comment.rb +29 -0
  247. data/lib/arel/nodes/count.rb +12 -0
  248. data/lib/arel/nodes/delete_statement.rb +45 -0
  249. data/lib/arel/nodes/descending.rb +23 -0
  250. data/lib/arel/nodes/equality.rb +15 -0
  251. data/lib/arel/nodes/extract.rb +24 -0
  252. data/lib/arel/nodes/false.rb +16 -0
  253. data/lib/arel/nodes/full_outer_join.rb +8 -0
  254. data/lib/arel/nodes/function.rb +44 -0
  255. data/lib/arel/nodes/grouping.rb +11 -0
  256. data/lib/arel/nodes/homogeneous_in.rb +72 -0
  257. data/lib/arel/nodes/in.rb +15 -0
  258. data/lib/arel/nodes/infix_operation.rb +92 -0
  259. data/lib/arel/nodes/inner_join.rb +8 -0
  260. data/lib/arel/nodes/insert_statement.rb +37 -0
  261. data/lib/arel/nodes/join_source.rb +20 -0
  262. data/lib/arel/nodes/matches.rb +18 -0
  263. data/lib/arel/nodes/named_function.rb +23 -0
  264. data/lib/arel/nodes/node.rb +51 -0
  265. data/lib/arel/nodes/node_expression.rb +13 -0
  266. data/lib/arel/nodes/ordering.rb +27 -0
  267. data/lib/arel/nodes/outer_join.rb +8 -0
  268. data/lib/arel/nodes/over.rb +15 -0
  269. data/lib/arel/nodes/regexp.rb +16 -0
  270. data/lib/arel/nodes/right_outer_join.rb +8 -0
  271. data/lib/arel/nodes/select_core.rb +67 -0
  272. data/lib/arel/nodes/select_statement.rb +41 -0
  273. data/lib/arel/nodes/sql_literal.rb +19 -0
  274. data/lib/arel/nodes/string_join.rb +11 -0
  275. data/lib/arel/nodes/table_alias.rb +31 -0
  276. data/lib/arel/nodes/terminal.rb +16 -0
  277. data/lib/arel/nodes/true.rb +16 -0
  278. data/lib/arel/nodes/unary.rb +44 -0
  279. data/lib/arel/nodes/unary_operation.rb +20 -0
  280. data/lib/arel/nodes/unqualified_column.rb +22 -0
  281. data/lib/arel/nodes/update_statement.rb +41 -0
  282. data/lib/arel/nodes/values_list.rb +9 -0
  283. data/lib/arel/nodes/window.rb +126 -0
  284. data/lib/arel/nodes/with.rb +11 -0
  285. data/lib/arel/nodes.rb +70 -0
  286. data/lib/arel/order_predications.rb +13 -0
  287. data/lib/arel/predications.rb +250 -0
  288. data/lib/arel/select_manager.rb +270 -0
  289. data/lib/arel/table.rb +118 -0
  290. data/lib/arel/tree_manager.rb +72 -0
  291. data/lib/arel/update_manager.rb +34 -0
  292. data/lib/arel/visitors/dot.rb +308 -0
  293. data/lib/arel/visitors/mysql.rb +93 -0
  294. data/lib/arel/visitors/postgresql.rb +120 -0
  295. data/lib/arel/visitors/sqlite.rb +38 -0
  296. data/lib/arel/visitors/to_sql.rb +899 -0
  297. data/lib/arel/visitors/visitor.rb +45 -0
  298. data/lib/arel/visitors.rb +13 -0
  299. data/lib/arel/window_predications.rb +9 -0
  300. data/lib/arel.rb +54 -0
  301. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  302. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -5
  303. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +3 -1
  304. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +7 -5
  305. data/lib/rails/generators/active_record/migration.rb +19 -2
  306. data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
  307. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  308. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  309. metadata +117 -32
  310. data/lib/active_record/attribute_decorators.rb +0 -90
  311. data/lib/active_record/collection_cache_key.rb +0 -53
  312. data/lib/active_record/connection_adapters/connection_specification.rb +0 -287
  313. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -33
  314. data/lib/active_record/define_callbacks.rb +0 -22
  315. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -19
  316. data/lib/active_record/relation/where_clause_factory.rb +0 -34
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/core_ext/enumerable"
3
4
  require "active_support/core_ext/hash/indifferent_access"
4
5
  require "active_support/core_ext/string/filters"
6
+ require "active_support/parameter_filter"
5
7
  require "concurrent/map"
6
8
 
7
9
  module ActiveRecord
@@ -24,9 +26,21 @@ module ActiveRecord
24
26
  # their relevant queries. Defaults to false.
25
27
  mattr_accessor :verbose_query_logs, instance_writer: false, default: false
26
28
 
29
+ ##
30
+ # :singleton-method:
31
+ #
32
+ # Specifies the names of the queues used by background jobs.
33
+ mattr_accessor :queues, instance_accessor: false, default: {}
34
+
35
+ ##
36
+ # :singleton-method:
37
+ #
38
+ # Specifies the job used to destroy associations in the background
39
+ class_attribute :destroy_association_async_job, instance_writer: false, instance_predicate: false, default: false
40
+
27
41
  ##
28
42
  # Contains the database configuration - as is typically stored in config/database.yml -
29
- # as a Hash.
43
+ # as an ActiveRecord::DatabaseConfigurations object.
30
44
  #
31
45
  # For example, the following database.yml...
32
46
  #
@@ -40,22 +54,18 @@ module ActiveRecord
40
54
  #
41
55
  # ...would result in ActiveRecord::Base.configurations to look like this:
42
56
  #
43
- # {
44
- # 'development' => {
45
- # 'adapter' => 'sqlite3',
46
- # 'database' => 'db/development.sqlite3'
47
- # },
48
- # 'production' => {
49
- # 'adapter' => 'sqlite3',
50
- # 'database' => 'db/production.sqlite3'
51
- # }
52
- # }
57
+ # #<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[
58
+ # #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
59
+ # @name="primary", @config={adapter: "sqlite3", database: "db/development.sqlite3"}>,
60
+ # #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90 @env_name="production",
61
+ # @name="primary", @config={adapter: "sqlite3", database: "db/production.sqlite3"}>
62
+ # ]>
53
63
  def self.configurations=(config)
54
- @@configurations = ActiveRecord::ConnectionHandling::MergeAndResolveDefaultUrlConfig.new(config).resolve
64
+ @@configurations = ActiveRecord::DatabaseConfigurations.new(config)
55
65
  end
56
66
  self.configurations = {}
57
67
 
58
- # Returns fully resolved configurations hash
68
+ # Returns fully resolved ActiveRecord::DatabaseConfigurations object
59
69
  def self.configurations
60
70
  @@configurations
61
71
  end
@@ -83,14 +93,6 @@ module ActiveRecord
83
93
  # scope being ignored is error-worthy, rather than a warning.
84
94
  mattr_accessor :error_on_ignored_order, instance_writer: false, default: false
85
95
 
86
- # :singleton-method:
87
- # Specify the behavior for unsafe raw query methods. Values are as follows
88
- # deprecated - Warnings are logged when unsafe raw SQL is passed to
89
- # query methods.
90
- # disabled - Unsafe raw SQL passed to query methods results in
91
- # UnknownAttributeReference exception.
92
- mattr_accessor :allow_unsafe_raw_sql, instance_writer: false, default: :deprecated
93
-
94
96
  ##
95
97
  # :singleton-method:
96
98
  # Specify whether or not to use timestamps for migration versions
@@ -99,14 +101,14 @@ module ActiveRecord
99
101
  ##
100
102
  # :singleton-method:
101
103
  # Specify whether schema dump should happen at the end of the
102
- # db:migrate rake task. This is true by default, which is useful for the
104
+ # db:migrate rails command. This is true by default, which is useful for the
103
105
  # development environment. This should ideally be false in the production
104
106
  # environment where dumping schema is rarely needed.
105
107
  mattr_accessor :dump_schema_after_migration, instance_writer: false, default: true
106
108
 
107
109
  ##
108
110
  # :singleton-method:
109
- # Specifies which database schemas to dump when calling db:structure:dump.
111
+ # Specifies which database schemas to dump when calling db:schema:dump.
110
112
  # If the value is :schema_search_path (the default), any schemas listed in
111
113
  # schema_search_path are dumped. Use :all to dump all schemas regardless
112
114
  # of schema_search_path, or a string of comma separated schemas for a
@@ -121,29 +123,173 @@ module ActiveRecord
121
123
  # potentially cause memory bloat.
122
124
  mattr_accessor :warn_on_records_fetched_greater_than, instance_writer: false
123
125
 
126
+ ##
127
+ # :singleton-method:
128
+ # Show a warning when Rails couldn't parse your database.yml
129
+ # for multiple databases.
130
+ mattr_accessor :suppress_multiple_database_warning, instance_writer: false, default: false
131
+
124
132
  mattr_accessor :maintain_test_schema, instance_accessor: false
125
133
 
126
- mattr_accessor :belongs_to_required_by_default, instance_accessor: false
134
+ class_attribute :belongs_to_required_by_default, instance_accessor: false
135
+
136
+ ##
137
+ # :singleton-method:
138
+ # Set the application to log or raise when an association violates strict loading.
139
+ # Defaults to :raise.
140
+ mattr_accessor :action_on_strict_loading_violation, instance_accessor: false, default: :raise
141
+
142
+ class_attribute :strict_loading_by_default, instance_accessor: false, default: false
143
+
144
+ mattr_accessor :writing_role, instance_accessor: false, default: :writing
145
+
146
+ mattr_accessor :reading_role, instance_accessor: false, default: :reading
147
+
148
+ mattr_accessor :has_many_inversing, instance_accessor: false, default: false
127
149
 
128
150
  class_attribute :default_connection_handler, instance_writer: false
129
151
 
152
+ class_attribute :default_role, instance_writer: false
153
+
154
+ class_attribute :default_shard, instance_writer: false
155
+
156
+ mattr_accessor :legacy_connection_handling, instance_writer: false, default: true
157
+
158
+ self.filter_attributes = []
159
+
130
160
  def self.connection_handler
131
- ActiveRecord::RuntimeRegistry.connection_handler || default_connection_handler
161
+ Thread.current.thread_variable_get(:ar_connection_handler) || default_connection_handler
132
162
  end
133
163
 
134
164
  def self.connection_handler=(handler)
135
- ActiveRecord::RuntimeRegistry.connection_handler = handler
165
+ Thread.current.thread_variable_set(:ar_connection_handler, handler)
136
166
  end
137
167
 
138
- self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
139
- end
168
+ def self.connection_handlers
169
+ unless legacy_connection_handling
170
+ raise NotImplementedError, "The new connection handling does not support accessing multiple connection handlers."
171
+ end
140
172
 
141
- module ClassMethods # :nodoc:
142
- def allocate
143
- define_attribute_methods
144
- super
173
+ @@connection_handlers ||= {}
174
+ end
175
+
176
+ def self.connection_handlers=(handlers)
177
+ unless legacy_connection_handling
178
+ raise NotImplementedError, "The new connection handling does not setting support multiple connection handlers."
179
+ end
180
+
181
+ @@connection_handlers = handlers
182
+ end
183
+
184
+ # Returns the symbol representing the current connected role.
185
+ #
186
+ # ActiveRecord::Base.connected_to(role: :writing) do
187
+ # ActiveRecord::Base.current_role #=> :writing
188
+ # end
189
+ #
190
+ # ActiveRecord::Base.connected_to(role: :reading) do
191
+ # ActiveRecord::Base.current_role #=> :reading
192
+ # end
193
+ def self.current_role
194
+ if ActiveRecord::Base.legacy_connection_handling
195
+ connection_handlers.key(connection_handler) || default_role
196
+ else
197
+ connected_to_stack.reverse_each do |hash|
198
+ return hash[:role] if hash[:role] && hash[:klasses].include?(Base)
199
+ return hash[:role] if hash[:role] && hash[:klasses].include?(abstract_base_class)
200
+ end
201
+
202
+ default_role
203
+ end
204
+ end
205
+
206
+ # Returns the symbol representing the current connected shard.
207
+ #
208
+ # ActiveRecord::Base.connected_to(role: :reading) do
209
+ # ActiveRecord::Base.current_shard #=> :default
210
+ # end
211
+ #
212
+ # ActiveRecord::Base.connected_to(role: :writing, shard: :one) do
213
+ # ActiveRecord::Base.current_shard #=> :one
214
+ # end
215
+ def self.current_shard
216
+ connected_to_stack.reverse_each do |hash|
217
+ return hash[:shard] if hash[:shard] && hash[:klasses].include?(Base)
218
+ return hash[:shard] if hash[:shard] && hash[:klasses].include?(abstract_base_class)
219
+ end
220
+
221
+ default_shard
222
+ end
223
+
224
+ # Returns the symbol representing the current setting for
225
+ # preventing writes.
226
+ #
227
+ # ActiveRecord::Base.connected_to(role: :reading) do
228
+ # ActiveRecord::Base.current_preventing_writes #=> true
229
+ # end
230
+ #
231
+ # ActiveRecord::Base.connected_to(role: :writing) do
232
+ # ActiveRecord::Base.current_preventing_writes #=> false
233
+ # end
234
+ def self.current_preventing_writes
235
+ if legacy_connection_handling
236
+ connection_handler.prevent_writes
237
+ else
238
+ connected_to_stack.reverse_each do |hash|
239
+ return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(Base)
240
+ return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(abstract_base_class)
241
+ end
242
+
243
+ false
244
+ end
245
+ end
246
+
247
+ def self.connected_to_stack # :nodoc:
248
+ if connected_to_stack = Thread.current.thread_variable_get(:ar_connected_to_stack)
249
+ connected_to_stack
250
+ else
251
+ connected_to_stack = Concurrent::Array.new
252
+ Thread.current.thread_variable_set(:ar_connected_to_stack, connected_to_stack)
253
+ connected_to_stack
254
+ end
255
+ end
256
+
257
+ def self.abstract_base_class # :nodoc:
258
+ klass = self
259
+
260
+ until klass == Base
261
+ break if klass.abstract_class?
262
+ klass = klass.superclass
263
+ end
264
+
265
+ klass
266
+ end
267
+
268
+ def self.allow_unsafe_raw_sql # :nodoc:
269
+ ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_unsafe_raw_sql is deprecated and will be removed in Rails 6.2")
270
+ end
271
+
272
+ def self.allow_unsafe_raw_sql=(value) # :nodoc:
273
+ ActiveSupport::Deprecation.warn("ActiveRecord::Base.allow_unsafe_raw_sql= is deprecated and will be removed in Rails 6.2")
274
+ end
275
+
276
+ self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
277
+ self.default_role = writing_role
278
+ self.default_shard = :default
279
+
280
+ def self.strict_loading_violation!(owner:, association:) # :nodoc:
281
+ case action_on_strict_loading_violation
282
+ when :raise
283
+ message = "`#{association}` called on `#{owner}` is marked for strict_loading and cannot be lazily loaded."
284
+ raise ActiveRecord::StrictLoadingViolationError.new(message)
285
+ when :log
286
+ name = "strict_loading_violation.active_record"
287
+ ActiveSupport::Notifications.instrument(name, owner: owner, association: association)
288
+ end
145
289
  end
290
+ end
146
291
 
292
+ module ClassMethods
147
293
  def initialize_find_by_cache # :nodoc:
148
294
  @find_by_statement_cache = { true => Concurrent::Map.new, false => Concurrent::Map.new }
149
295
  end
@@ -151,16 +297,20 @@ module ActiveRecord
151
297
  def inherited(child_class) # :nodoc:
152
298
  # initialize cache at class definition for thread safety
153
299
  child_class.initialize_find_by_cache
300
+ unless child_class.base_class?
301
+ klass = self
302
+ until klass.base_class?
303
+ klass.initialize_find_by_cache
304
+ klass = klass.superclass
305
+ end
306
+ end
154
307
  super
155
308
  end
156
309
 
157
310
  def find(*ids) # :nodoc:
158
311
  # We don't have cache keys for this stuff yet
159
312
  return super unless ids.length == 1
160
- return super if block_given? ||
161
- primary_key.nil? ||
162
- scope_attributes? ||
163
- columns_hash.include?(inheritance_column)
313
+ return super if block_given? || primary_key.nil? || scope_attributes?
164
314
 
165
315
  id = ids.first
166
316
 
@@ -172,44 +322,43 @@ module ActiveRecord
172
322
  where(key => params.bind).limit(1)
173
323
  }
174
324
 
175
- record = statement.execute([id], connection).first
176
- unless record
177
- raise RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}",
178
- name, primary_key, id)
179
- end
180
- record
181
- rescue ::RangeError
182
- raise RecordNotFound.new("Couldn't find #{name} with an out of range value for '#{primary_key}'",
183
- name, primary_key)
325
+ statement.execute([id], connection).first ||
326
+ raise(RecordNotFound.new("Couldn't find #{name} with '#{key}'=#{id}", name, key, id))
184
327
  end
185
328
 
186
329
  def find_by(*args) # :nodoc:
187
- return super if scope_attributes? || reflect_on_all_aggregations.any? ||
188
- columns_hash.key?(inheritance_column) && base_class != self
330
+ return super if scope_attributes?
189
331
 
190
332
  hash = args.first
333
+ return super unless Hash === hash
334
+
335
+ values = hash.values.map! { |value| value.respond_to?(:id) ? value.id : value }
336
+ return super if values.any? { |v| StatementCache.unsupported_value?(v) }
337
+
338
+ keys = hash.keys.map! do |key|
339
+ attribute_aliases[name = key.to_s] || begin
340
+ reflection = _reflect_on_association(name)
341
+ if reflection&.belongs_to? && !reflection.polymorphic?
342
+ reflection.join_foreign_key
343
+ elsif reflect_on_aggregation(name)
344
+ return super
345
+ else
346
+ name
347
+ end
348
+ end
349
+ end
191
350
 
192
- return super if !(Hash === hash) || hash.values.any? { |v|
193
- StatementCache.unsupported_value?(v)
194
- }
195
-
196
- # We can't cache Post.find_by(author: david) ...yet
197
- return super unless hash.keys.all? { |k| columns_hash.has_key?(k.to_s) }
198
-
199
- keys = hash.keys
351
+ return super unless keys.all? { |k| columns_hash.key?(k) }
200
352
 
201
353
  statement = cached_find_by_statement(keys) { |params|
202
- wheres = keys.each_with_object({}) { |param, o|
203
- o[param] = params.bind
204
- }
354
+ wheres = keys.index_with { params.bind }
205
355
  where(wheres).limit(1)
206
356
  }
357
+
207
358
  begin
208
- statement.execute(hash.values, connection).first
359
+ statement.execute(values, connection).first
209
360
  rescue TypeError
210
361
  raise ActiveRecord::StatementInvalid
211
- rescue ::RangeError
212
- nil
213
362
  end
214
363
  end
215
364
 
@@ -221,7 +370,7 @@ module ActiveRecord
221
370
  generated_association_methods
222
371
  end
223
372
 
224
- def generated_association_methods
373
+ def generated_association_methods # :nodoc:
225
374
  @generated_association_methods ||= begin
226
375
  mod = const_set(:GeneratedAssociationMethods, Module.new)
227
376
  private_constant :GeneratedAssociationMethods
@@ -231,8 +380,20 @@ module ActiveRecord
231
380
  end
232
381
  end
233
382
 
383
+ # Returns columns which shouldn't be exposed while calling +#inspect+.
384
+ def filter_attributes
385
+ if defined?(@filter_attributes)
386
+ @filter_attributes
387
+ else
388
+ superclass.filter_attributes
389
+ end
390
+ end
391
+
392
+ # Specifies columns which shouldn't be exposed while calling +#inspect+.
393
+ attr_writer :filter_attributes
394
+
234
395
  # Returns a string like 'Post(id:integer, title:string, body:text)'
235
- def inspect
396
+ def inspect # :nodoc:
236
397
  if self == Base
237
398
  super
238
399
  elsif abstract_class?
@@ -248,7 +409,7 @@ module ActiveRecord
248
409
  end
249
410
 
250
411
  # Overwrite the default class equality method to provide support for decorated models.
251
- def ===(object)
412
+ def ===(object) # :nodoc:
252
413
  object.is_a?(self)
253
414
  end
254
415
 
@@ -258,13 +419,13 @@ module ActiveRecord
258
419
  # scope :published_and_commented, -> { published.and(arel_table[:comments_count].gt(0)) }
259
420
  # end
260
421
  def arel_table # :nodoc:
261
- @arel_table ||= Arel::Table.new(table_name, type_caster: type_caster)
422
+ @arel_table ||= Arel::Table.new(table_name, klass: self)
262
423
  end
263
424
 
264
425
  def arel_attribute(name, table = arel_table) # :nodoc:
265
- name = attribute_alias(name) if attribute_alias?(name)
266
426
  table[name]
267
427
  end
428
+ deprecate :arel_attribute
268
429
 
269
430
  def predicate_builder # :nodoc:
270
431
  @predicate_builder ||= PredicateBuilder.new(table_metadata)
@@ -274,19 +435,21 @@ module ActiveRecord
274
435
  TypeCaster::Map.new(self)
275
436
  end
276
437
 
277
- private
438
+ def _internal? # :nodoc:
439
+ false
440
+ end
278
441
 
279
- def cached_find_by_statement(key, &block)
280
- cache = @find_by_statement_cache[connection.prepared_statements]
281
- cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
282
- end
442
+ def cached_find_by_statement(key, &block) # :nodoc:
443
+ cache = @find_by_statement_cache[connection.prepared_statements]
444
+ cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
445
+ end
283
446
 
447
+ private
284
448
  def relation
285
449
  relation = Relation.create(self)
286
450
 
287
451
  if finder_needs_type_condition? && !ignore_default_scope?
288
452
  relation.where!(type_condition)
289
- relation.create_with!(inheritance_column.to_s => sti_name)
290
453
  else
291
454
  relation
292
455
  end
@@ -306,7 +469,7 @@ module ActiveRecord
306
469
  # # Instantiates a single new object
307
470
  # User.new(first_name: 'Jamie')
308
471
  def initialize(attributes = nil)
309
- self.class.define_attribute_methods
472
+ @new_record = true
310
473
  @attributes = self.class._default_attributes.deep_dup
311
474
 
312
475
  init_internals
@@ -332,15 +495,21 @@ module ActiveRecord
332
495
  # post = Post.allocate
333
496
  # post.init_with(coder)
334
497
  # post.title # => 'hello world'
335
- def init_with(coder)
498
+ def init_with(coder, &block)
336
499
  coder = LegacyYamlAdapter.convert(self.class, coder)
337
- @attributes = self.class.yaml_encoder.decode(coder)
338
-
339
- init_internals
500
+ attributes = self.class.yaml_encoder.decode(coder)
501
+ init_with_attributes(attributes, coder["new_record"], &block)
502
+ end
340
503
 
341
- @new_record = coder["new_record"]
504
+ ##
505
+ # Initialize an empty model object from +attributes+.
506
+ # +attributes+ should be an attributes object, and unlike the
507
+ # `initialize` method, no assignment calls are made per attribute.
508
+ def init_with_attributes(attributes, new_record = false) # :nodoc:
509
+ @new_record = new_record
510
+ @attributes = attributes
342
511
 
343
- self.class.define_attribute_methods
512
+ init_internals
344
513
 
345
514
  yield self if block_given?
346
515
 
@@ -379,14 +548,14 @@ module ActiveRecord
379
548
  ##
380
549
  def initialize_dup(other) # :nodoc:
381
550
  @attributes = @attributes.deep_dup
382
- @attributes.reset(self.class.primary_key)
551
+ @attributes.reset(@primary_key)
383
552
 
384
553
  _run_initialize_callbacks
385
554
 
386
555
  @new_record = true
556
+ @previously_new_record = false
387
557
  @destroyed = false
388
- @_start_transaction_state = {}
389
- @transaction_state = nil
558
+ @_start_transaction_state = nil
390
559
 
391
560
  super
392
561
  end
@@ -458,12 +627,35 @@ module ActiveRecord
458
627
  end
459
628
  end
460
629
 
461
- # Returns +true+ if the record is read only. Records loaded through joins with piggy-back
462
- # attributes will be marked as read only since they cannot be saved.
630
+ def present? # :nodoc:
631
+ true
632
+ end
633
+
634
+ def blank? # :nodoc:
635
+ false
636
+ end
637
+
638
+ # Returns +true+ if the record is read only.
463
639
  def readonly?
464
640
  @readonly
465
641
  end
466
642
 
643
+ # Returns +true+ if the record is in strict_loading mode.
644
+ def strict_loading?
645
+ @strict_loading
646
+ end
647
+
648
+ # Sets the record to strict_loading mode. This will raise an error
649
+ # if the record tries to lazily load an association.
650
+ #
651
+ # user = User.first
652
+ # user.strict_loading!
653
+ # user.comments.to_a
654
+ # => ActiveRecord::StrictLoadingViolationError
655
+ def strict_loading!
656
+ @strict_loading = true
657
+ end
658
+
467
659
  # Marks this record as read only.
468
660
  def readonly!
469
661
  @readonly = true
@@ -479,7 +671,7 @@ module ActiveRecord
479
671
  # allocated but not initialized.
480
672
  inspection = if defined?(@attributes) && @attributes
481
673
  self.class.attribute_names.collect do |name|
482
- if has_attribute?(name)
674
+ if _has_attribute?(name)
483
675
  "#{name}: #{attribute_for_inspect(name)}"
484
676
  end
485
677
  end.compact.join(", ")
@@ -496,15 +688,16 @@ module ActiveRecord
496
688
  return super if custom_inspect_method_defined?
497
689
  pp.object_address_group(self) do
498
690
  if defined?(@attributes) && @attributes
499
- column_names = self.class.column_names.select { |name| has_attribute?(name) || new_record? }
500
- pp.seplist(column_names, proc { pp.text "," }) do |column_name|
501
- column_value = read_attribute(column_name)
691
+ attr_names = self.class.attribute_names.select { |name| _has_attribute?(name) }
692
+ pp.seplist(attr_names, proc { pp.text "," }) do |attr_name|
502
693
  pp.breakable " "
503
694
  pp.group(1) do
504
- pp.text column_name
695
+ pp.text attr_name
505
696
  pp.text ":"
506
697
  pp.breakable
507
- pp.pp column_value
698
+ value = _read_attribute(attr_name)
699
+ value = inspection_filter.filter_param(attr_name, value) unless value.nil?
700
+ pp.pp value
508
701
  end
509
702
  end
510
703
  else
@@ -516,11 +709,15 @@ module ActiveRecord
516
709
 
517
710
  # Returns a hash of the given methods with their names as keys and returned values as values.
518
711
  def slice(*methods)
519
- Hash[methods.flatten.map! { |method| [method, public_send(method)] }].with_indifferent_access
712
+ methods.flatten.index_with { |method| public_send(method) }.with_indifferent_access
520
713
  end
521
714
 
522
- private
715
+ # Returns an array of the values returned by the given methods.
716
+ def values_at(*methods)
717
+ methods.flatten.map! { |method| public_send(method) }
718
+ end
523
719
 
720
+ private
524
721
  # +Array#flatten+ will call +#to_ary+ (recursively) on each of the elements of
525
722
  # the array, and then rescues from the possible +NoMethodError+. If those elements are
526
723
  # +ActiveRecord::Base+'s, then this triggers the various +method_missing+'s that we have,
@@ -534,26 +731,37 @@ module ActiveRecord
534
731
  end
535
732
 
536
733
  def init_internals
734
+ @primary_key = self.class.primary_key
537
735
  @readonly = false
736
+ @previously_new_record = false
538
737
  @destroyed = false
539
738
  @marked_for_destruction = false
540
739
  @destroyed_by_association = nil
541
- @new_record = true
542
- @_start_transaction_state = {}
543
- @transaction_state = nil
740
+ @_start_transaction_state = nil
741
+ @strict_loading = self.class.strict_loading_by_default
742
+
743
+ self.class.define_attribute_methods
544
744
  end
545
745
 
546
746
  def initialize_internals_callback
547
747
  end
548
748
 
549
- def thaw
550
- if frozen?
551
- @attributes = @attributes.dup
749
+ def custom_inspect_method_defined?
750
+ self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner
751
+ end
752
+
753
+ class InspectionMask < DelegateClass(::String)
754
+ def pretty_print(pp)
755
+ pp.text __getobj__
552
756
  end
553
757
  end
758
+ private_constant :InspectionMask
554
759
 
555
- def custom_inspect_method_defined?
556
- self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner
760
+ def inspection_filter
761
+ @inspection_filter ||= begin
762
+ mask = InspectionMask.new(ActiveSupport::ParameterFilter::FILTERED)
763
+ ActiveSupport::ParameterFilter.new(self.class.filter_attributes, mask: mask)
764
+ end
557
765
  end
558
766
  end
559
767
  end