activerecord 5.2.8.1 → 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 +849 -630
  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 +8 -17
  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 +24 -18
  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 +41 -20
  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 +47 -34
  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 +57 -42
  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 +2 -15
  51. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +272 -130
  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 +18 -14
  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 +174 -186
  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 +304 -106
  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 +4 -4
  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 +113 -74
  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 +109 -93
  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 +153 -90
  169. data/lib/active_record/relation/delegation.rb +35 -50
  170. data/lib/active_record/relation/finder_methods.rb +64 -39
  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 +472 -186
  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 +4 -6
  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 +49 -6
  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 +58 -116
  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 +120 -35
  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,39 +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
127
135
 
128
136
  ##
129
137
  # :singleton-method:
130
- # Application configurable boolean that instructs the YAML Coder to use
131
- # an unsafe load if set to true.
132
- mattr_accessor :use_yaml_unsafe_load, instance_writer: false, default: false
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
133
145
 
134
- # Application configurable array that provides additional permitted classes
135
- # to Psych safe_load in the YAML Coder
136
- mattr_accessor :yaml_column_permitted_classes, instance_writer: false, default: []
146
+ mattr_accessor :reading_role, instance_accessor: false, default: :reading
147
+
148
+ mattr_accessor :has_many_inversing, instance_accessor: false, default: false
137
149
 
138
150
  class_attribute :default_connection_handler, instance_writer: false
139
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
+
140
160
  def self.connection_handler
141
- ActiveRecord::RuntimeRegistry.connection_handler || default_connection_handler
161
+ Thread.current.thread_variable_get(:ar_connection_handler) || default_connection_handler
142
162
  end
143
163
 
144
164
  def self.connection_handler=(handler)
145
- ActiveRecord::RuntimeRegistry.connection_handler = handler
165
+ Thread.current.thread_variable_set(:ar_connection_handler, handler)
146
166
  end
147
167
 
148
- self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
149
- 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
150
172
 
151
- module ClassMethods # :nodoc:
152
- def allocate
153
- define_attribute_methods
154
- 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
155
255
  end
156
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
289
+ end
290
+ end
291
+
292
+ module ClassMethods
157
293
  def initialize_find_by_cache # :nodoc:
158
294
  @find_by_statement_cache = { true => Concurrent::Map.new, false => Concurrent::Map.new }
159
295
  end
@@ -161,16 +297,20 @@ module ActiveRecord
161
297
  def inherited(child_class) # :nodoc:
162
298
  # initialize cache at class definition for thread safety
163
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
164
307
  super
165
308
  end
166
309
 
167
310
  def find(*ids) # :nodoc:
168
311
  # We don't have cache keys for this stuff yet
169
312
  return super unless ids.length == 1
170
- return super if block_given? ||
171
- primary_key.nil? ||
172
- scope_attributes? ||
173
- columns_hash.include?(inheritance_column)
313
+ return super if block_given? || primary_key.nil? || scope_attributes?
174
314
 
175
315
  id = ids.first
176
316
 
@@ -182,44 +322,43 @@ module ActiveRecord
182
322
  where(key => params.bind).limit(1)
183
323
  }
184
324
 
185
- record = statement.execute([id], connection).first
186
- unless record
187
- raise RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}",
188
- name, primary_key, id)
189
- end
190
- record
191
- rescue ::RangeError
192
- raise RecordNotFound.new("Couldn't find #{name} with an out of range value for '#{primary_key}'",
193
- name, primary_key)
325
+ statement.execute([id], connection).first ||
326
+ raise(RecordNotFound.new("Couldn't find #{name} with '#{key}'=#{id}", name, key, id))
194
327
  end
195
328
 
196
329
  def find_by(*args) # :nodoc:
197
- return super if scope_attributes? || reflect_on_all_aggregations.any? ||
198
- columns_hash.key?(inheritance_column) && base_class != self
330
+ return super if scope_attributes?
199
331
 
200
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
201
350
 
202
- return super if !(Hash === hash) || hash.values.any? { |v|
203
- StatementCache.unsupported_value?(v)
204
- }
205
-
206
- # We can't cache Post.find_by(author: david) ...yet
207
- return super unless hash.keys.all? { |k| columns_hash.has_key?(k.to_s) }
208
-
209
- keys = hash.keys
351
+ return super unless keys.all? { |k| columns_hash.key?(k) }
210
352
 
211
353
  statement = cached_find_by_statement(keys) { |params|
212
- wheres = keys.each_with_object({}) { |param, o|
213
- o[param] = params.bind
214
- }
354
+ wheres = keys.index_with { params.bind }
215
355
  where(wheres).limit(1)
216
356
  }
357
+
217
358
  begin
218
- statement.execute(hash.values, connection).first
359
+ statement.execute(values, connection).first
219
360
  rescue TypeError
220
361
  raise ActiveRecord::StatementInvalid
221
- rescue ::RangeError
222
- nil
223
362
  end
224
363
  end
225
364
 
@@ -231,7 +370,7 @@ module ActiveRecord
231
370
  generated_association_methods
232
371
  end
233
372
 
234
- def generated_association_methods
373
+ def generated_association_methods # :nodoc:
235
374
  @generated_association_methods ||= begin
236
375
  mod = const_set(:GeneratedAssociationMethods, Module.new)
237
376
  private_constant :GeneratedAssociationMethods
@@ -241,8 +380,20 @@ module ActiveRecord
241
380
  end
242
381
  end
243
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
+
244
395
  # Returns a string like 'Post(id:integer, title:string, body:text)'
245
- def inspect
396
+ def inspect # :nodoc:
246
397
  if self == Base
247
398
  super
248
399
  elsif abstract_class?
@@ -258,7 +409,7 @@ module ActiveRecord
258
409
  end
259
410
 
260
411
  # Overwrite the default class equality method to provide support for decorated models.
261
- def ===(object)
412
+ def ===(object) # :nodoc:
262
413
  object.is_a?(self)
263
414
  end
264
415
 
@@ -268,13 +419,13 @@ module ActiveRecord
268
419
  # scope :published_and_commented, -> { published.and(arel_table[:comments_count].gt(0)) }
269
420
  # end
270
421
  def arel_table # :nodoc:
271
- @arel_table ||= Arel::Table.new(table_name, type_caster: type_caster)
422
+ @arel_table ||= Arel::Table.new(table_name, klass: self)
272
423
  end
273
424
 
274
425
  def arel_attribute(name, table = arel_table) # :nodoc:
275
- name = attribute_alias(name) if attribute_alias?(name)
276
426
  table[name]
277
427
  end
428
+ deprecate :arel_attribute
278
429
 
279
430
  def predicate_builder # :nodoc:
280
431
  @predicate_builder ||= PredicateBuilder.new(table_metadata)
@@ -284,19 +435,21 @@ module ActiveRecord
284
435
  TypeCaster::Map.new(self)
285
436
  end
286
437
 
287
- private
438
+ def _internal? # :nodoc:
439
+ false
440
+ end
288
441
 
289
- def cached_find_by_statement(key, &block)
290
- cache = @find_by_statement_cache[connection.prepared_statements]
291
- cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
292
- 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
293
446
 
447
+ private
294
448
  def relation
295
449
  relation = Relation.create(self)
296
450
 
297
451
  if finder_needs_type_condition? && !ignore_default_scope?
298
452
  relation.where!(type_condition)
299
- relation.create_with!(inheritance_column.to_s => sti_name)
300
453
  else
301
454
  relation
302
455
  end
@@ -316,7 +469,7 @@ module ActiveRecord
316
469
  # # Instantiates a single new object
317
470
  # User.new(first_name: 'Jamie')
318
471
  def initialize(attributes = nil)
319
- self.class.define_attribute_methods
472
+ @new_record = true
320
473
  @attributes = self.class._default_attributes.deep_dup
321
474
 
322
475
  init_internals
@@ -342,15 +495,21 @@ module ActiveRecord
342
495
  # post = Post.allocate
343
496
  # post.init_with(coder)
344
497
  # post.title # => 'hello world'
345
- def init_with(coder)
498
+ def init_with(coder, &block)
346
499
  coder = LegacyYamlAdapter.convert(self.class, coder)
347
- @attributes = self.class.yaml_encoder.decode(coder)
348
-
349
- init_internals
500
+ attributes = self.class.yaml_encoder.decode(coder)
501
+ init_with_attributes(attributes, coder["new_record"], &block)
502
+ end
350
503
 
351
- @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
352
511
 
353
- self.class.define_attribute_methods
512
+ init_internals
354
513
 
355
514
  yield self if block_given?
356
515
 
@@ -389,14 +548,14 @@ module ActiveRecord
389
548
  ##
390
549
  def initialize_dup(other) # :nodoc:
391
550
  @attributes = @attributes.deep_dup
392
- @attributes.reset(self.class.primary_key)
551
+ @attributes.reset(@primary_key)
393
552
 
394
553
  _run_initialize_callbacks
395
554
 
396
555
  @new_record = true
556
+ @previously_new_record = false
397
557
  @destroyed = false
398
- @_start_transaction_state = {}
399
- @transaction_state = nil
558
+ @_start_transaction_state = nil
400
559
 
401
560
  super
402
561
  end
@@ -468,12 +627,35 @@ module ActiveRecord
468
627
  end
469
628
  end
470
629
 
471
- # Returns +true+ if the record is read only. Records loaded through joins with piggy-back
472
- # 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.
473
639
  def readonly?
474
640
  @readonly
475
641
  end
476
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
+
477
659
  # Marks this record as read only.
478
660
  def readonly!
479
661
  @readonly = true
@@ -489,7 +671,7 @@ module ActiveRecord
489
671
  # allocated but not initialized.
490
672
  inspection = if defined?(@attributes) && @attributes
491
673
  self.class.attribute_names.collect do |name|
492
- if has_attribute?(name)
674
+ if _has_attribute?(name)
493
675
  "#{name}: #{attribute_for_inspect(name)}"
494
676
  end
495
677
  end.compact.join(", ")
@@ -506,15 +688,16 @@ module ActiveRecord
506
688
  return super if custom_inspect_method_defined?
507
689
  pp.object_address_group(self) do
508
690
  if defined?(@attributes) && @attributes
509
- column_names = self.class.column_names.select { |name| has_attribute?(name) || new_record? }
510
- pp.seplist(column_names, proc { pp.text "," }) do |column_name|
511
- 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|
512
693
  pp.breakable " "
513
694
  pp.group(1) do
514
- pp.text column_name
695
+ pp.text attr_name
515
696
  pp.text ":"
516
697
  pp.breakable
517
- 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
518
701
  end
519
702
  end
520
703
  else
@@ -526,11 +709,15 @@ module ActiveRecord
526
709
 
527
710
  # Returns a hash of the given methods with their names as keys and returned values as values.
528
711
  def slice(*methods)
529
- Hash[methods.flatten.map! { |method| [method, public_send(method)] }].with_indifferent_access
712
+ methods.flatten.index_with { |method| public_send(method) }.with_indifferent_access
530
713
  end
531
714
 
532
- 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
533
719
 
720
+ private
534
721
  # +Array#flatten+ will call +#to_ary+ (recursively) on each of the elements of
535
722
  # the array, and then rescues from the possible +NoMethodError+. If those elements are
536
723
  # +ActiveRecord::Base+'s, then this triggers the various +method_missing+'s that we have,
@@ -544,26 +731,37 @@ module ActiveRecord
544
731
  end
545
732
 
546
733
  def init_internals
734
+ @primary_key = self.class.primary_key
547
735
  @readonly = false
736
+ @previously_new_record = false
548
737
  @destroyed = false
549
738
  @marked_for_destruction = false
550
739
  @destroyed_by_association = nil
551
- @new_record = true
552
- @_start_transaction_state = {}
553
- @transaction_state = nil
740
+ @_start_transaction_state = nil
741
+ @strict_loading = self.class.strict_loading_by_default
742
+
743
+ self.class.define_attribute_methods
554
744
  end
555
745
 
556
746
  def initialize_internals_callback
557
747
  end
558
748
 
559
- def thaw
560
- if frozen?
561
- @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__
562
756
  end
563
757
  end
758
+ private_constant :InspectionMask
564
759
 
565
- def custom_inspect_method_defined?
566
- 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
567
765
  end
568
766
  end
569
767
  end