activerecord 5.2.8.1 → 6.1.6.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (316) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1255 -596
  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 +9 -8
  7. data/lib/active_record/association_relation.rb +30 -10
  8. data/lib/active_record/associations/alias_tracker.rb +19 -16
  9. data/lib/active_record/associations/association.rb +100 -41
  10. data/lib/active_record/associations/association_scope.rb +23 -21
  11. data/lib/active_record/associations/belongs_to_association.rb +55 -48
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -6
  13. data/lib/active_record/associations/builder/association.rb +45 -22
  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 +44 -34
  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 +44 -22
  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 +69 -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 +137 -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 +46 -9
  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 +1 -2
  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 +211 -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 +385 -144
  61. data/lib/active_record/connection_adapters/abstract/transaction.rb +167 -69
  62. data/lib/active_record/connection_adapters/abstract_adapter.rb +229 -99
  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 +35 -0
  67. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  68. data/lib/active_record/connection_adapters/mysql/database_statements.rb +88 -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 +59 -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 +18 -7
  74. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +142 -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 +73 -0
  78. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  79. data/lib/active_record/connection_adapters/postgresql/column.rb +37 -28
  80. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +40 -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/oid.rb +1 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
  93. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
  94. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  96. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
  97. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/quoting.rb +47 -10
  99. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
  100. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +19 -4
  101. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
  102. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  103. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +120 -100
  104. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
  105. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  106. data/lib/active_record/connection_adapters/postgresql_adapter.rb +224 -120
  107. data/lib/active_record/connection_adapters/schema_cache.rb +159 -21
  108. data/lib/active_record/connection_adapters/sql_type_metadata.rb +17 -6
  109. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +146 -0
  110. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
  111. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  112. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +77 -13
  113. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +174 -186
  114. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  115. data/lib/active_record/connection_adapters.rb +52 -0
  116. data/lib/active_record/connection_handling.rb +293 -33
  117. data/lib/active_record/core.rb +333 -98
  118. data/lib/active_record/counter_cache.rb +8 -30
  119. data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -0
  120. data/lib/active_record/database_configurations/database_config.rb +80 -0
  121. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  122. data/lib/active_record/database_configurations/url_config.rb +53 -0
  123. data/lib/active_record/database_configurations.rb +273 -0
  124. data/lib/active_record/delegated_type.rb +209 -0
  125. data/lib/active_record/destroy_association_async_job.rb +36 -0
  126. data/lib/active_record/dynamic_matchers.rb +3 -4
  127. data/lib/active_record/enum.rb +108 -36
  128. data/lib/active_record/errors.rb +62 -19
  129. data/lib/active_record/explain.rb +10 -6
  130. data/lib/active_record/explain_subscriber.rb +1 -1
  131. data/lib/active_record/fixture_set/file.rb +10 -17
  132. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  133. data/lib/active_record/fixture_set/render_context.rb +17 -0
  134. data/lib/active_record/fixture_set/table_row.rb +152 -0
  135. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  136. data/lib/active_record/fixtures.rb +200 -481
  137. data/lib/active_record/gem_version.rb +3 -3
  138. data/lib/active_record/inheritance.rb +53 -24
  139. data/lib/active_record/insert_all.rb +212 -0
  140. data/lib/active_record/integration.rb +67 -17
  141. data/lib/active_record/internal_metadata.rb +28 -9
  142. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  143. data/lib/active_record/locking/optimistic.rb +37 -23
  144. data/lib/active_record/locking/pessimistic.rb +9 -5
  145. data/lib/active_record/log_subscriber.rb +35 -35
  146. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  147. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  148. data/lib/active_record/middleware/database_selector.rb +77 -0
  149. data/lib/active_record/migration/command_recorder.rb +96 -44
  150. data/lib/active_record/migration/compatibility.rb +145 -64
  151. data/lib/active_record/migration/join_table.rb +0 -1
  152. data/lib/active_record/migration.rb +206 -157
  153. data/lib/active_record/model_schema.rb +148 -22
  154. data/lib/active_record/nested_attributes.rb +4 -7
  155. data/lib/active_record/no_touching.rb +8 -1
  156. data/lib/active_record/null_relation.rb +0 -1
  157. data/lib/active_record/persistence.rb +267 -59
  158. data/lib/active_record/query_cache.rb +21 -4
  159. data/lib/active_record/querying.rb +40 -23
  160. data/lib/active_record/railtie.rb +116 -59
  161. data/lib/active_record/railties/console_sandbox.rb +2 -4
  162. data/lib/active_record/railties/controller_runtime.rb +30 -35
  163. data/lib/active_record/railties/databases.rake +411 -80
  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 +157 -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 +11 -10
  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 +62 -45
  180. data/lib/active_record/relation/query_attribute.rb +13 -8
  181. data/lib/active_record/relation/query_methods.rb +476 -187
  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 +115 -62
  185. data/lib/active_record/relation.rb +379 -115
  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 -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 +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 +42 -43
  202. data/lib/active_record/tasks/database_tasks.rb +277 -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 +287 -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 +62 -118
  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 +76 -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 +116 -30
  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
@@ -2,36 +2,42 @@
2
2
 
3
3
  module ActiveRecord
4
4
  module Querying
5
- delegate :find, :take, :take!, :first, :first!, :last, :last!, :exists?, :any?, :many?, :none?, :one?, to: :all
6
- delegate :second, :second!, :third, :third!, :fourth, :fourth!, :fifth, :fifth!, :forty_two, :forty_two!, :third_to_last, :third_to_last!, :second_to_last, :second_to_last!, to: :all
7
- delegate :first_or_create, :first_or_create!, :first_or_initialize, to: :all
8
- delegate :find_or_create_by, :find_or_create_by!, :find_or_initialize_by, to: :all
9
- delegate :find_by, :find_by!, to: :all
10
- delegate :destroy_all, :delete_all, :update_all, to: :all
11
- delegate :find_each, :find_in_batches, :in_batches, to: :all
12
- delegate :select, :group, :order, :except, :reorder, :limit, :offset, :joins, :left_joins, :left_outer_joins, :or,
13
- :where, :rewhere, :preload, :eager_load, :includes, :from, :lock, :readonly, :extending,
14
- :having, :create_with, :distinct, :references, :none, :unscope, :merge, to: :all
15
- delegate :count, :average, :minimum, :maximum, :sum, :calculate, to: :all
16
- delegate :pluck, :ids, to: :all
5
+ QUERYING_METHODS = [
6
+ :find, :find_by, :find_by!, :take, :take!, :first, :first!, :last, :last!,
7
+ :second, :second!, :third, :third!, :fourth, :fourth!, :fifth, :fifth!,
8
+ :forty_two, :forty_two!, :third_to_last, :third_to_last!, :second_to_last, :second_to_last!,
9
+ :exists?, :any?, :many?, :none?, :one?,
10
+ :first_or_create, :first_or_create!, :first_or_initialize,
11
+ :find_or_create_by, :find_or_create_by!, :find_or_initialize_by,
12
+ :create_or_find_by, :create_or_find_by!,
13
+ :destroy_all, :delete_all, :update_all, :touch_all, :destroy_by, :delete_by,
14
+ :find_each, :find_in_batches, :in_batches,
15
+ :select, :reselect, :order, :reorder, :group, :limit, :offset, :joins, :left_joins, :left_outer_joins,
16
+ :where, :rewhere, :preload, :extract_associated, :eager_load, :includes, :from, :lock, :readonly,
17
+ :and, :or, :annotate, :optimizer_hints, :extending,
18
+ :having, :create_with, :distinct, :references, :none, :unscope, :merge, :except, :only,
19
+ :count, :average, :minimum, :maximum, :sum, :calculate,
20
+ :pluck, :pick, :ids, :strict_loading
21
+ ].freeze # :nodoc:
22
+ delegate(*QUERYING_METHODS, to: :all)
17
23
 
18
24
  # Executes a custom SQL query against your database and returns all the results. The results will
19
- # be returned as an array with columns requested encapsulated as attributes of the model you call
20
- # this method from. If you call <tt>Product.find_by_sql</tt> then the results will be returned in
25
+ # be returned as an array, with the requested columns encapsulated as attributes of the model you call
26
+ # this method from. For example, if you call <tt>Product.find_by_sql</tt>, then the results will be returned in
21
27
  # a +Product+ object with the attributes you specified in the SQL query.
22
28
  #
23
- # If you call a complicated SQL query which spans multiple tables the columns specified by the
29
+ # If you call a complicated SQL query which spans multiple tables, the columns specified by the
24
30
  # SELECT will be attributes of the model, whether or not they are columns of the corresponding
25
31
  # table.
26
32
  #
27
- # The +sql+ parameter is a full SQL query as a string. It will be called as is, there will be
28
- # no database agnostic conversions performed. This should be a last resort because using, for example,
29
- # MySQL specific terms will lock you to using that particular database engine or require you to
33
+ # The +sql+ parameter is a full SQL query as a string. It will be called as is; there will be
34
+ # no database agnostic conversions performed. This should be a last resort because using
35
+ # database-specific terms will lock you into using that particular database engine, or require you to
30
36
  # change your call if you switch engines.
31
37
  #
32
38
  # # A simple SQL query spanning multiple tables
33
39
  # Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
34
- # # => [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "first_name"=>"Quentin"}>, ...]
40
+ # # => [#<Post:0x36bff9c @attributes={"title"=>"Ruby Meetup", "author"=>"Quentin"}>, ...]
35
41
  #
36
42
  # You can use the same string replacement techniques as you can with <tt>ActiveRecord::QueryMethods#where</tt>:
37
43
  #
@@ -39,8 +45,12 @@ module ActiveRecord
39
45
  # Post.find_by_sql ["SELECT body FROM comments WHERE author = :user_id OR approved_by = :user_id", { :user_id => user_id }]
40
46
  def find_by_sql(sql, binds = [], preparable: nil, &block)
41
47
  result_set = connection.select_all(sanitize_sql(sql), "#{name} Load", binds, preparable: preparable)
42
- column_types = result_set.column_types.dup
43
- attribute_types.each_key { |k| column_types.delete k }
48
+ column_types = result_set.column_types
49
+
50
+ unless column_types.empty?
51
+ column_types = column_types.reject { |k, _| attribute_types.key?(k) }
52
+ end
53
+
44
54
  message_bus = ActiveSupport::Notifications.instrumenter
45
55
 
46
56
  payload = {
@@ -49,13 +59,20 @@ module ActiveRecord
49
59
  }
50
60
 
51
61
  message_bus.instrument("instantiation.active_record", payload) do
52
- result_set.map { |record| instantiate(record, column_types, &block) }
62
+ if result_set.includes_column?(inheritance_column)
63
+ result_set.map { |record| instantiate(record, column_types, &block) }
64
+ else
65
+ # Instantiate a homogeneous set
66
+ result_set.map { |record| instantiate_instance_of(self, record, column_types, &block) }
67
+ end
53
68
  end
54
69
  end
55
70
 
56
71
  # Returns the result of an SQL statement that should only include a COUNT(*) in the SELECT part.
57
72
  # The use of this method should be restricted to complicated SQL queries that can't be executed
58
- # using the ActiveRecord::Calculations class methods. Look into those before using this.
73
+ # using the ActiveRecord::Calculations class methods. Look into those before using this method,
74
+ # as it could lock you into a specific database engine or require a code change to switch
75
+ # database engines.
59
76
  #
60
77
  # Product.count_by_sql "SELECT COUNT(*) FROM sales s, customers c WHERE s.customer_id = c.id"
61
78
  # # => 12
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "active_record"
4
4
  require "rails"
5
+ require "active_support/core_ext/object/try"
5
6
  require "active_model/railtie"
6
7
 
7
8
  # For now, action_controller must always be present with
@@ -26,18 +27,17 @@ module ActiveRecord
26
27
  )
27
28
 
28
29
  config.active_record.use_schema_cache_dump = true
30
+ config.active_record.check_schema_cache_dump_version = true
29
31
  config.active_record.maintain_test_schema = true
32
+ config.active_record.has_many_inversing = false
30
33
 
31
- config.active_record.sqlite3 = ActiveSupport::OrderedOptions.new
32
- config.active_record.sqlite3.represent_boolean_as_integer = nil
34
+ config.active_record.queues = ActiveSupport::InheritableOptions.new
33
35
 
34
36
  config.eager_load_namespaces << ActiveRecord
35
37
 
36
38
  rake_tasks do
37
39
  namespace :db do
38
40
  task :load_config do
39
- ActiveRecord::Tasks::DatabaseTasks.database_configuration = Rails.application.config.database_configuration
40
-
41
41
  if defined?(ENGINE_ROOT) && engine = Rails::Engine.find(ENGINE_ROOT)
42
42
  if engine.paths["db/migrate"].existent
43
43
  ActiveRecord::Tasks::DatabaseTasks.migrations_paths += engine.paths["db/migrate"].to_a
@@ -57,6 +57,7 @@ module ActiveRecord
57
57
  require "active_record/base"
58
58
  unless ActiveSupport::Logger.logger_outputs_to?(Rails.logger, STDERR, STDOUT)
59
59
  console = ActiveSupport::Logger.new(STDERR)
60
+ console.level = Rails.logger.level
60
61
  Rails.logger.extend ActiveSupport::Logger.broadcast console
61
62
  end
62
63
  ActiveRecord::Base.verbose_query_logs = false
@@ -77,31 +78,115 @@ module ActiveRecord
77
78
  ActiveSupport.on_load(:active_record) { self.logger ||= ::Rails.logger }
78
79
  end
79
80
 
80
- initializer "active_record.migration_error" do
81
+ initializer "active_record.backtrace_cleaner" do
82
+ ActiveSupport.on_load(:active_record) { LogSubscriber.backtrace_cleaner = ::Rails.backtrace_cleaner }
83
+ end
84
+
85
+ initializer "active_record.migration_error" do |app|
81
86
  if config.active_record.delete(:migration_error) == :page_load
82
87
  config.app_middleware.insert_after ::ActionDispatch::Callbacks,
83
- ActiveRecord::Migration::CheckPending
88
+ ActiveRecord::Migration::CheckPending,
89
+ file_watcher: app.config.file_watcher
90
+ end
91
+ end
92
+
93
+ initializer "active_record.database_selector" do
94
+ if options = config.active_record.delete(:database_selector)
95
+ resolver = config.active_record.delete(:database_resolver)
96
+ operations = config.active_record.delete(:database_resolver_context)
97
+ config.app_middleware.use ActiveRecord::Middleware::DatabaseSelector, resolver, operations, options
98
+ end
99
+ end
100
+
101
+ initializer "Check for cache versioning support" do
102
+ config.after_initialize do |app|
103
+ ActiveSupport.on_load(:active_record) do
104
+ if app.config.active_record.cache_versioning && Rails.cache
105
+ unless Rails.cache.class.try(:supports_cache_versioning?)
106
+ raise <<-end_error
107
+
108
+ You're using a cache store that doesn't support native cache versioning.
109
+ Your best option is to upgrade to a newer version of #{Rails.cache.class}
110
+ that supports cache versioning (#{Rails.cache.class}.supports_cache_versioning? #=> true).
111
+
112
+ Next best, switch to a different cache store that does support cache versioning:
113
+ https://guides.rubyonrails.org/caching_with_rails.html#cache-stores.
114
+
115
+ To keep using the current cache store, you can turn off cache versioning entirely:
116
+
117
+ config.active_record.cache_versioning = false
118
+
119
+ end_error
120
+ end
121
+ end
122
+ end
84
123
  end
85
124
  end
86
125
 
87
126
  initializer "active_record.check_schema_cache_dump" do
127
+ check_schema_cache_dump_version = config.active_record.delete(:check_schema_cache_dump_version)
128
+
88
129
  if config.active_record.delete(:use_schema_cache_dump)
89
130
  config.after_initialize do |app|
90
131
  ActiveSupport.on_load(:active_record) do
91
- filename = File.join(app.config.paths["db"].first, "schema_cache.yml")
132
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).first
133
+
134
+ filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(
135
+ db_config.name,
136
+ schema_cache_path: db_config&.schema_cache_path
137
+ )
138
+
139
+ cache = ActiveRecord::ConnectionAdapters::SchemaCache.load_from(filename)
140
+ next if cache.nil?
141
+
142
+ if check_schema_cache_dump_version
143
+ current_version = begin
144
+ ActiveRecord::Migrator.current_version
145
+ rescue ActiveRecordError => error
146
+ warn "Failed to validate the schema cache because of #{error.class}: #{error.message}"
147
+ nil
148
+ end
149
+ next if current_version.nil?
92
150
 
93
- if File.file?(filename)
94
- current_version = ActiveRecord::Migrator.current_version
151
+ if cache.version != current_version
152
+ warn "Ignoring #{filename} because it has expired. The current schema version is #{current_version}, but the one in the cache is #{cache.version}."
153
+ next
154
+ end
155
+ end
95
156
 
96
- next if current_version.nil?
157
+ connection_pool.set_schema_cache(cache)
158
+ end
159
+ end
160
+ end
161
+ end
97
162
 
98
- cache = YAML.load(File.read(filename))
99
- if cache.version == current_version
100
- connection.schema_cache = cache
101
- connection_pool.schema_cache = cache.dup
102
- else
103
- warn "Ignoring db/schema_cache.yml because it has expired. The current schema version is #{current_version}, but the one in the cache is #{cache.version}."
163
+ initializer "active_record.define_attribute_methods" do |app|
164
+ config.after_initialize do
165
+ ActiveSupport.on_load(:active_record) do
166
+ if app.config.eager_load
167
+ begin
168
+ descendants.each do |model|
169
+ # SchemaMigration and InternalMetadata both override `table_exists?`
170
+ # to bypass the schema cache, so skip them to avoid the extra queries.
171
+ next if model._internal?
172
+
173
+ # If the schema cache was loaded from a dump, we can use it without connecting
174
+ schema_cache = model.connection_pool.schema_cache
175
+
176
+ # If there's no connection yet, we avoid connecting.
177
+ schema_cache ||= model.connected? && model.connection.schema_cache
178
+
179
+ # If the schema cache doesn't have the columns
180
+ # hash for the model cached, `define_attribute_methods` would trigger a query.
181
+ if schema_cache && schema_cache.columns_hash?(model.table_name)
182
+ model.define_attribute_methods
183
+ end
104
184
  end
185
+ rescue ActiveRecordError => error
186
+ # Regardless of whether there was already a connection or not, we rescue any database
187
+ # error because it is critical that the application can boot even if the database
188
+ # is unhealthy.
189
+ warn "Failed to define attribute methods because of #{error.class}: #{error.message}"
105
190
  end
106
191
  end
107
192
  end
@@ -118,8 +203,8 @@ module ActiveRecord
118
203
 
119
204
  initializer "active_record.set_configs" do |app|
120
205
  ActiveSupport.on_load(:active_record) do
121
- configs = app.config.active_record.dup
122
- configs.delete(:sqlite3)
206
+ configs = app.config.active_record
207
+
123
208
  configs.each do |k, v|
124
209
  send "#{k}=", v
125
210
  end
@@ -130,22 +215,11 @@ module ActiveRecord
130
215
  # and then establishes the connection.
131
216
  initializer "active_record.initialize_database" do
132
217
  ActiveSupport.on_load(:active_record) do
133
- self.configurations = Rails.application.config.database_configuration
134
-
135
- begin
136
- establish_connection
137
- rescue ActiveRecord::NoDatabaseError
138
- warn <<-end_warning
139
- Oops - You have a database configured, but it doesn't exist yet!
140
-
141
- Here's how to get started:
142
-
143
- 1. Configure your database in config/database.yml.
144
- 2. Run `bin/rails db:create` to create the database.
145
- 3. Run `bin/rails db:setup` to load your database schema.
146
- end_warning
147
- raise
218
+ if ActiveRecord::Base.legacy_connection_handling
219
+ self.connection_handlers = { writing_role => ActiveRecord::Base.default_connection_handler }
148
220
  end
221
+ self.configurations = Rails.application.config.database_configuration
222
+ establish_connection
149
223
  end
150
224
  end
151
225
 
@@ -194,35 +268,18 @@ end_warning
194
268
  end
195
269
  end
196
270
 
197
- initializer "active_record.check_represent_sqlite3_boolean_as_integer" do
198
- config.after_initialize do
199
- ActiveSupport.on_load(:active_record_sqlite3adapter) do
200
- represent_boolean_as_integer = Rails.application.config.active_record.sqlite3.delete(:represent_boolean_as_integer)
201
- unless represent_boolean_as_integer.nil?
202
- ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer = represent_boolean_as_integer
203
- end
204
-
205
- unless ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer
206
- ActiveSupport::Deprecation.warn <<-MSG
207
- Leaving `ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer`
208
- set to false is deprecated. SQLite databases have used 't' and 'f' to serialize
209
- boolean values and must have old data converted to 1 and 0 (its native boolean
210
- serialization) before setting this flag to true. Conversion can be accomplished
211
- by setting up a rake task which runs
212
-
213
- ExampleModel.where("boolean_column = 't'").update_all(boolean_column: 1)
214
- ExampleModel.where("boolean_column = 'f'").update_all(boolean_column: 0)
215
-
216
- for all models and all boolean columns, after which the flag must be set to
217
- true by adding the following to your application.rb file:
271
+ initializer "active_record.set_filter_attributes" do
272
+ ActiveSupport.on_load(:active_record) do
273
+ self.filter_attributes += Rails.application.config.filter_parameters
274
+ end
275
+ end
218
276
 
219
- Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
220
- MSG
221
- end
222
- end
277
+ initializer "active_record.set_signed_id_verifier_secret" do
278
+ ActiveSupport.on_load(:active_record) do
279
+ self.signed_id_verifier_secret ||= -> { Rails.application.key_generator.generate_key("active_record/signed_id") }
223
280
  end
224
281
  end
225
-
282
+
226
283
  initializer "active_record.use_yaml_unsafe_load" do |app|
227
284
  config.after_initialize do
228
285
  unless app.config.active_record.use_yaml_unsafe_load.nil?
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- ActiveRecord::Base.connection.begin_transaction(joinable: false)
4
-
5
- at_exit do
6
- ActiveRecord::Base.connection.rollback_transaction
3
+ ActiveRecord::ConnectionAdapters::AbstractAdapter.set_callback(:checkout, :after) do
4
+ begin_transaction(joinable: false)
7
5
  end
@@ -8,49 +8,44 @@ module ActiveRecord
8
8
  module ControllerRuntime #:nodoc:
9
9
  extend ActiveSupport::Concern
10
10
 
11
- # TODO Change this to private once we've dropped Ruby 2.2 support.
12
- # Workaround for Ruby 2.2 "private attribute?" warning.
13
- protected
14
-
15
- attr_internal :db_runtime
16
-
17
- private
18
-
19
- def process_action(action, *args)
20
- # We also need to reset the runtime before each action
21
- # because of queries in middleware or in cases we are streaming
22
- # and it won't be cleaned up by the method below.
23
- ActiveRecord::LogSubscriber.reset_runtime
24
- super
11
+ module ClassMethods # :nodoc:
12
+ def log_process_action(payload)
13
+ messages, db_runtime = super, payload[:db_runtime]
14
+ messages << ("ActiveRecord: %.1fms" % db_runtime.to_f) if db_runtime
15
+ messages
16
+ end
25
17
  end
26
18
 
27
- def cleanup_view_runtime
28
- if logger && logger.info? && ActiveRecord::Base.connected?
29
- db_rt_before_render = ActiveRecord::LogSubscriber.reset_runtime
30
- self.db_runtime = (db_runtime || 0) + db_rt_before_render
31
- runtime = super
32
- db_rt_after_render = ActiveRecord::LogSubscriber.reset_runtime
33
- self.db_runtime += db_rt_after_render
34
- runtime - db_rt_after_render
35
- else
19
+ private
20
+ attr_internal :db_runtime
21
+
22
+ def process_action(action, *args)
23
+ # We also need to reset the runtime before each action
24
+ # because of queries in middleware or in cases we are streaming
25
+ # and it won't be cleaned up by the method below.
26
+ ActiveRecord::LogSubscriber.reset_runtime
36
27
  super
37
28
  end
38
- end
39
29
 
40
- def append_info_to_payload(payload)
41
- super
42
- if ActiveRecord::Base.connected?
43
- payload[:db_runtime] = (db_runtime || 0) + ActiveRecord::LogSubscriber.reset_runtime
30
+ def cleanup_view_runtime
31
+ if logger && logger.info? && ActiveRecord::Base.connected?
32
+ db_rt_before_render = ActiveRecord::LogSubscriber.reset_runtime
33
+ self.db_runtime = (db_runtime || 0) + db_rt_before_render
34
+ runtime = super
35
+ db_rt_after_render = ActiveRecord::LogSubscriber.reset_runtime
36
+ self.db_runtime += db_rt_after_render
37
+ runtime - db_rt_after_render
38
+ else
39
+ super
40
+ end
44
41
  end
45
- end
46
42
 
47
- module ClassMethods # :nodoc:
48
- def log_process_action(payload)
49
- messages, db_runtime = super, payload[:db_runtime]
50
- messages << ("ActiveRecord: %.1fms" % db_runtime.to_f) if db_runtime
51
- messages
43
+ def append_info_to_payload(payload)
44
+ super
45
+ if ActiveRecord::Base.connected?
46
+ payload[:db_runtime] = (db_runtime || 0) + ActiveRecord::LogSubscriber.reset_runtime
47
+ end
52
48
  end
53
- end
54
49
  end
55
50
  end
56
51
  end