activerecord 5.2.8 → 7.0.2

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 (364) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1393 -587
  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 +10 -9
  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 +122 -47
  10. data/lib/active_record/associations/association_scope.rb +24 -24
  11. data/lib/active_record/associations/belongs_to_association.rb +67 -49
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +16 -7
  13. data/lib/active_record/associations/builder/association.rb +52 -23
  14. data/lib/active_record/associations/builder/belongs_to.rb +44 -61
  15. data/lib/active_record/associations/builder/collection_association.rb +17 -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 +10 -3
  18. data/lib/active_record/associations/builder/has_one.rb +35 -3
  19. data/lib/active_record/associations/builder/singular_association.rb +5 -3
  20. data/lib/active_record/associations/collection_association.rb +59 -50
  21. data/lib/active_record/associations/collection_proxy.rb +32 -23
  22. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  23. data/lib/active_record/associations/foreign_association.rb +20 -0
  24. data/lib/active_record/associations/has_many_association.rb +27 -14
  25. data/lib/active_record/associations/has_many_through_association.rb +26 -19
  26. data/lib/active_record/associations/has_one_association.rb +52 -37
  27. data/lib/active_record/associations/has_one_through_association.rb +6 -6
  28. data/lib/active_record/associations/join_dependency/join_association.rb +44 -22
  29. data/lib/active_record/associations/join_dependency/join_part.rb +5 -5
  30. data/lib/active_record/associations/join_dependency.rb +97 -62
  31. data/lib/active_record/associations/preloader/association.rb +220 -60
  32. data/lib/active_record/associations/preloader/batch.rb +48 -0
  33. data/lib/active_record/associations/preloader/branch.rb +147 -0
  34. data/lib/active_record/associations/preloader/through_association.rb +85 -40
  35. data/lib/active_record/associations/preloader.rb +44 -105
  36. data/lib/active_record/associations/singular_association.rb +9 -17
  37. data/lib/active_record/associations/through_association.rb +4 -4
  38. data/lib/active_record/associations.rb +207 -66
  39. data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
  40. data/lib/active_record/attribute_assignment.rb +17 -19
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +19 -8
  42. data/lib/active_record/attribute_methods/dirty.rb +141 -47
  43. data/lib/active_record/attribute_methods/primary_key.rb +22 -27
  44. data/lib/active_record/attribute_methods/query.rb +6 -10
  45. data/lib/active_record/attribute_methods/read.rb +15 -55
  46. data/lib/active_record/attribute_methods/serialization.rb +77 -18
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +16 -18
  48. data/lib/active_record/attribute_methods/write.rb +18 -37
  49. data/lib/active_record/attribute_methods.rb +90 -153
  50. data/lib/active_record/attributes.rb +38 -12
  51. data/lib/active_record/autosave_association.rb +50 -50
  52. data/lib/active_record/base.rb +23 -18
  53. data/lib/active_record/callbacks.rb +159 -44
  54. data/lib/active_record/coders/yaml_column.rb +12 -3
  55. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
  57. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
  58. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +92 -464
  59. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -51
  60. data/lib/active_record/connection_adapters/abstract/database_statements.rb +209 -164
  61. data/lib/active_record/connection_adapters/abstract/query_cache.rb +38 -22
  62. data/lib/active_record/connection_adapters/abstract/quoting.rb +103 -82
  63. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  64. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +140 -110
  65. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +236 -94
  66. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +16 -5
  67. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +456 -159
  68. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
  69. data/lib/active_record/connection_adapters/abstract_adapter.rb +367 -162
  70. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +311 -327
  71. data/lib/active_record/connection_adapters/column.rb +33 -11
  72. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  73. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  74. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  75. data/lib/active_record/connection_adapters/mysql/database_statements.rb +113 -45
  76. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
  77. data/lib/active_record/connection_adapters/mysql/quoting.rb +71 -5
  78. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +34 -10
  79. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +48 -32
  80. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +25 -8
  81. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +143 -19
  82. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +14 -9
  83. data/lib/active_record/connection_adapters/mysql2_adapter.rb +63 -22
  84. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  85. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  86. data/lib/active_record/connection_adapters/postgresql/column.rb +53 -28
  87. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +56 -63
  88. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  90. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  91. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +10 -2
  92. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +15 -2
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +54 -16
  95. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +3 -4
  97. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  102. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +26 -12
  105. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +4 -0
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +89 -52
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +34 -2
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +39 -4
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +128 -91
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -1
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +149 -113
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +386 -182
  116. data/lib/active_record/connection_adapters/schema_cache.rb +161 -22
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +17 -6
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +152 -0
  119. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +65 -18
  120. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  121. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +92 -26
  122. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +251 -204
  123. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  124. data/lib/active_record/connection_adapters.rb +53 -0
  125. data/lib/active_record/connection_handling.rb +292 -38
  126. data/lib/active_record/core.rb +385 -158
  127. data/lib/active_record/counter_cache.rb +8 -30
  128. data/lib/active_record/database_configurations/connection_url_resolver.rb +100 -0
  129. data/lib/active_record/database_configurations/database_config.rb +83 -0
  130. data/lib/active_record/database_configurations/hash_config.rb +154 -0
  131. data/lib/active_record/database_configurations/url_config.rb +53 -0
  132. data/lib/active_record/database_configurations.rb +256 -0
  133. data/lib/active_record/delegated_type.rb +250 -0
  134. data/lib/active_record/destroy_association_async_job.rb +36 -0
  135. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  136. data/lib/active_record/dynamic_matchers.rb +4 -5
  137. data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
  138. data/lib/active_record/encryption/cipher.rb +53 -0
  139. data/lib/active_record/encryption/config.rb +44 -0
  140. data/lib/active_record/encryption/configurable.rb +61 -0
  141. data/lib/active_record/encryption/context.rb +35 -0
  142. data/lib/active_record/encryption/contexts.rb +72 -0
  143. data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
  144. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  145. data/lib/active_record/encryption/encryptable_record.rb +208 -0
  146. data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
  147. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  148. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  149. data/lib/active_record/encryption/encryptor.rb +155 -0
  150. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  151. data/lib/active_record/encryption/errors.rb +15 -0
  152. data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
  153. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  154. data/lib/active_record/encryption/key.rb +28 -0
  155. data/lib/active_record/encryption/key_generator.rb +42 -0
  156. data/lib/active_record/encryption/key_provider.rb +46 -0
  157. data/lib/active_record/encryption/message.rb +33 -0
  158. data/lib/active_record/encryption/message_serializer.rb +90 -0
  159. data/lib/active_record/encryption/null_encryptor.rb +21 -0
  160. data/lib/active_record/encryption/properties.rb +76 -0
  161. data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
  162. data/lib/active_record/encryption/scheme.rb +99 -0
  163. data/lib/active_record/encryption.rb +55 -0
  164. data/lib/active_record/enum.rb +130 -51
  165. data/lib/active_record/errors.rb +129 -23
  166. data/lib/active_record/explain.rb +10 -6
  167. data/lib/active_record/explain_registry.rb +11 -6
  168. data/lib/active_record/explain_subscriber.rb +1 -1
  169. data/lib/active_record/fixture_set/file.rb +22 -15
  170. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  171. data/lib/active_record/fixture_set/render_context.rb +17 -0
  172. data/lib/active_record/fixture_set/table_row.rb +187 -0
  173. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  174. data/lib/active_record/fixtures.rb +206 -490
  175. data/lib/active_record/future_result.rb +139 -0
  176. data/lib/active_record/gem_version.rb +3 -3
  177. data/lib/active_record/inheritance.rb +104 -37
  178. data/lib/active_record/insert_all.rb +278 -0
  179. data/lib/active_record/integration.rb +69 -18
  180. data/lib/active_record/internal_metadata.rb +24 -9
  181. data/lib/active_record/legacy_yaml_adapter.rb +3 -36
  182. data/lib/active_record/locking/optimistic.rb +41 -26
  183. data/lib/active_record/locking/pessimistic.rb +18 -8
  184. data/lib/active_record/log_subscriber.rb +46 -35
  185. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  186. data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
  187. data/lib/active_record/middleware/database_selector.rb +82 -0
  188. data/lib/active_record/middleware/shard_selector.rb +60 -0
  189. data/lib/active_record/migration/command_recorder.rb +96 -44
  190. data/lib/active_record/migration/compatibility.rb +246 -64
  191. data/lib/active_record/migration/join_table.rb +1 -2
  192. data/lib/active_record/migration.rb +266 -187
  193. data/lib/active_record/model_schema.rb +165 -52
  194. data/lib/active_record/nested_attributes.rb +17 -19
  195. data/lib/active_record/no_touching.rb +11 -4
  196. data/lib/active_record/null_relation.rb +2 -7
  197. data/lib/active_record/persistence.rb +467 -92
  198. data/lib/active_record/query_cache.rb +21 -4
  199. data/lib/active_record/query_logs.rb +138 -0
  200. data/lib/active_record/querying.rb +51 -24
  201. data/lib/active_record/railtie.rb +224 -57
  202. data/lib/active_record/railties/console_sandbox.rb +2 -4
  203. data/lib/active_record/railties/controller_runtime.rb +31 -36
  204. data/lib/active_record/railties/databases.rake +369 -101
  205. data/lib/active_record/readonly_attributes.rb +15 -0
  206. data/lib/active_record/reflection.rb +170 -137
  207. data/lib/active_record/relation/batches/batch_enumerator.rb +44 -14
  208. data/lib/active_record/relation/batches.rb +46 -37
  209. data/lib/active_record/relation/calculations.rb +168 -96
  210. data/lib/active_record/relation/delegation.rb +37 -52
  211. data/lib/active_record/relation/finder_methods.rb +79 -58
  212. data/lib/active_record/relation/from_clause.rb +5 -1
  213. data/lib/active_record/relation/merger.rb +50 -51
  214. data/lib/active_record/relation/predicate_builder/array_handler.rb +13 -13
  215. data/lib/active_record/relation/predicate_builder/association_query_value.rb +5 -9
  216. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  217. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +11 -10
  218. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  219. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  220. data/lib/active_record/relation/predicate_builder.rb +58 -46
  221. data/lib/active_record/relation/query_attribute.rb +9 -10
  222. data/lib/active_record/relation/query_methods.rb +685 -208
  223. data/lib/active_record/relation/record_fetch_warning.rb +9 -11
  224. data/lib/active_record/relation/spawn_methods.rb +10 -10
  225. data/lib/active_record/relation/where_clause.rb +108 -64
  226. data/lib/active_record/relation.rb +515 -151
  227. data/lib/active_record/result.rb +78 -42
  228. data/lib/active_record/runtime_registry.rb +9 -13
  229. data/lib/active_record/sanitization.rb +29 -44
  230. data/lib/active_record/schema.rb +37 -31
  231. data/lib/active_record/schema_dumper.rb +74 -23
  232. data/lib/active_record/schema_migration.rb +7 -9
  233. data/lib/active_record/scoping/default.rb +62 -17
  234. data/lib/active_record/scoping/named.rb +17 -32
  235. data/lib/active_record/scoping.rb +70 -41
  236. data/lib/active_record/secure_token.rb +16 -8
  237. data/lib/active_record/serialization.rb +6 -4
  238. data/lib/active_record/signed_id.rb +116 -0
  239. data/lib/active_record/statement_cache.rb +49 -6
  240. data/lib/active_record/store.rb +88 -9
  241. data/lib/active_record/suppressor.rb +13 -17
  242. data/lib/active_record/table_metadata.rb +42 -43
  243. data/lib/active_record/tasks/database_tasks.rb +352 -94
  244. data/lib/active_record/tasks/mysql_database_tasks.rb +37 -39
  245. data/lib/active_record/tasks/postgresql_database_tasks.rb +41 -39
  246. data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -17
  247. data/lib/active_record/test_databases.rb +24 -0
  248. data/lib/active_record/test_fixtures.rb +287 -0
  249. data/lib/active_record/timestamp.rb +44 -34
  250. data/lib/active_record/touch_later.rb +23 -22
  251. data/lib/active_record/transactions.rb +67 -128
  252. data/lib/active_record/translation.rb +3 -3
  253. data/lib/active_record/type/adapter_specific_registry.rb +34 -19
  254. data/lib/active_record/type/hash_lookup_type_map.rb +34 -2
  255. data/lib/active_record/type/internal/timezone.rb +2 -2
  256. data/lib/active_record/type/serialized.rb +7 -4
  257. data/lib/active_record/type/time.rb +10 -0
  258. data/lib/active_record/type/type_map.rb +17 -21
  259. data/lib/active_record/type/unsigned_integer.rb +0 -1
  260. data/lib/active_record/type.rb +9 -5
  261. data/lib/active_record/type_caster/connection.rb +15 -15
  262. data/lib/active_record/type_caster/map.rb +8 -8
  263. data/lib/active_record/validations/associated.rb +2 -3
  264. data/lib/active_record/validations/numericality.rb +35 -0
  265. data/lib/active_record/validations/uniqueness.rb +39 -31
  266. data/lib/active_record/validations.rb +4 -3
  267. data/lib/active_record.rb +209 -32
  268. data/lib/arel/alias_predication.rb +9 -0
  269. data/lib/arel/attributes/attribute.rb +33 -0
  270. data/lib/arel/collectors/bind.rb +29 -0
  271. data/lib/arel/collectors/composite.rb +39 -0
  272. data/lib/arel/collectors/plain_string.rb +20 -0
  273. data/lib/arel/collectors/sql_string.rb +27 -0
  274. data/lib/arel/collectors/substitute_binds.rb +35 -0
  275. data/lib/arel/crud.rb +48 -0
  276. data/lib/arel/delete_manager.rb +32 -0
  277. data/lib/arel/errors.rb +9 -0
  278. data/lib/arel/expressions.rb +29 -0
  279. data/lib/arel/factory_methods.rb +49 -0
  280. data/lib/arel/filter_predications.rb +9 -0
  281. data/lib/arel/insert_manager.rb +48 -0
  282. data/lib/arel/math.rb +45 -0
  283. data/lib/arel/nodes/and.rb +32 -0
  284. data/lib/arel/nodes/ascending.rb +23 -0
  285. data/lib/arel/nodes/binary.rb +126 -0
  286. data/lib/arel/nodes/bind_param.rb +44 -0
  287. data/lib/arel/nodes/case.rb +55 -0
  288. data/lib/arel/nodes/casted.rb +62 -0
  289. data/lib/arel/nodes/comment.rb +29 -0
  290. data/lib/arel/nodes/count.rb +12 -0
  291. data/lib/arel/nodes/delete_statement.rb +44 -0
  292. data/lib/arel/nodes/descending.rb +23 -0
  293. data/lib/arel/nodes/equality.rb +15 -0
  294. data/lib/arel/nodes/extract.rb +24 -0
  295. data/lib/arel/nodes/false.rb +16 -0
  296. data/lib/arel/nodes/filter.rb +10 -0
  297. data/lib/arel/nodes/full_outer_join.rb +8 -0
  298. data/lib/arel/nodes/function.rb +45 -0
  299. data/lib/arel/nodes/grouping.rb +11 -0
  300. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  301. data/lib/arel/nodes/in.rb +15 -0
  302. data/lib/arel/nodes/infix_operation.rb +92 -0
  303. data/lib/arel/nodes/inner_join.rb +8 -0
  304. data/lib/arel/nodes/insert_statement.rb +37 -0
  305. data/lib/arel/nodes/join_source.rb +20 -0
  306. data/lib/arel/nodes/matches.rb +18 -0
  307. data/lib/arel/nodes/named_function.rb +23 -0
  308. data/lib/arel/nodes/node.rb +51 -0
  309. data/lib/arel/nodes/node_expression.rb +13 -0
  310. data/lib/arel/nodes/ordering.rb +27 -0
  311. data/lib/arel/nodes/outer_join.rb +8 -0
  312. data/lib/arel/nodes/over.rb +15 -0
  313. data/lib/arel/nodes/regexp.rb +16 -0
  314. data/lib/arel/nodes/right_outer_join.rb +8 -0
  315. data/lib/arel/nodes/select_core.rb +67 -0
  316. data/lib/arel/nodes/select_statement.rb +41 -0
  317. data/lib/arel/nodes/sql_literal.rb +19 -0
  318. data/lib/arel/nodes/string_join.rb +11 -0
  319. data/lib/arel/nodes/table_alias.rb +31 -0
  320. data/lib/arel/nodes/terminal.rb +16 -0
  321. data/lib/arel/nodes/true.rb +16 -0
  322. data/lib/arel/nodes/unary.rb +44 -0
  323. data/lib/arel/nodes/unary_operation.rb +20 -0
  324. data/lib/arel/nodes/unqualified_column.rb +22 -0
  325. data/lib/arel/nodes/update_statement.rb +46 -0
  326. data/lib/arel/nodes/values_list.rb +9 -0
  327. data/lib/arel/nodes/window.rb +126 -0
  328. data/lib/arel/nodes/with.rb +11 -0
  329. data/lib/arel/nodes.rb +71 -0
  330. data/lib/arel/order_predications.rb +13 -0
  331. data/lib/arel/predications.rb +258 -0
  332. data/lib/arel/select_manager.rb +276 -0
  333. data/lib/arel/table.rb +117 -0
  334. data/lib/arel/tree_manager.rb +60 -0
  335. data/lib/arel/update_manager.rb +48 -0
  336. data/lib/arel/visitors/dot.rb +298 -0
  337. data/lib/arel/visitors/mysql.rb +99 -0
  338. data/lib/arel/visitors/postgresql.rb +110 -0
  339. data/lib/arel/visitors/sqlite.rb +38 -0
  340. data/lib/arel/visitors/to_sql.rb +955 -0
  341. data/lib/arel/visitors/visitor.rb +45 -0
  342. data/lib/arel/visitors.rb +13 -0
  343. data/lib/arel/window_predications.rb +9 -0
  344. data/lib/arel.rb +55 -0
  345. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  346. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  347. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -5
  348. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +3 -1
  349. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +7 -5
  350. data/lib/rails/generators/active_record/migration.rb +19 -2
  351. data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
  352. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  353. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  354. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  355. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  356. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  357. metadata +162 -32
  358. data/lib/active_record/attribute_decorators.rb +0 -90
  359. data/lib/active_record/collection_cache_key.rb +0 -53
  360. data/lib/active_record/connection_adapters/connection_specification.rb +0 -287
  361. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -33
  362. data/lib/active_record/define_callbacks.rb +0 -22
  363. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -19
  364. data/lib/active_record/relation/where_clause_factory.rb +0 -34
@@ -102,20 +102,61 @@ module ActiveRecord
102
102
  # If true, the default table name for a Product class will be "products". If false, it would just be "product".
103
103
  # See table_name for the full rules on table/class naming. This is true, by default.
104
104
 
105
- included do
106
- mattr_accessor :primary_key_prefix_type, instance_writer: false
105
+ ##
106
+ # :singleton-method: implicit_order_column
107
+ # :call-seq: implicit_order_column
108
+ #
109
+ # The name of the column records are ordered by if no explicit order clause
110
+ # is used during an ordered finder call. If not set the primary key is used.
111
+
112
+ ##
113
+ # :singleton-method: implicit_order_column=
114
+ # :call-seq: implicit_order_column=(column_name)
115
+ #
116
+ # Sets the column to sort records by when no explicit order clause is used
117
+ # during an ordered finder call. Useful when the primary key is not an
118
+ # auto-incrementing integer, for example when it's a UUID. Records are subsorted
119
+ # by the primary key if it exists to ensure deterministic results.
120
+
121
+ ##
122
+ # :singleton-method: immutable_strings_by_default=
123
+ # :call-seq: immutable_strings_by_default=(bool)
124
+ #
125
+ # Determines whether columns should infer their type as +:string+ or
126
+ # +:immutable_string+. This setting does not affect the behavior of
127
+ # <tt>attribute :foo, :string</tt>. Defaults to false.
107
128
 
129
+ included do
130
+ class_attribute :primary_key_prefix_type, instance_writer: false
108
131
  class_attribute :table_name_prefix, instance_writer: false, default: ""
109
132
  class_attribute :table_name_suffix, instance_writer: false, default: ""
110
133
  class_attribute :schema_migrations_table_name, instance_accessor: false, default: "schema_migrations"
111
134
  class_attribute :internal_metadata_table_name, instance_accessor: false, default: "ar_internal_metadata"
112
135
  class_attribute :pluralize_table_names, instance_writer: false, default: true
136
+ class_attribute :implicit_order_column, instance_accessor: false
137
+ class_attribute :immutable_strings_by_default, instance_accessor: false
138
+
139
+ # Defines the name of the table column which will store the class name on single-table
140
+ # inheritance situations.
141
+ #
142
+ # The default inheritance column name is +type+, which means it's a
143
+ # reserved word inside Active Record. To be able to use single-table
144
+ # inheritance with another column name, or to use the column +type+ in
145
+ # your own model for something else, you can set +inheritance_column+:
146
+ #
147
+ # self.inheritance_column = 'zoink'
148
+ class_attribute :inheritance_column, instance_accessor: false, default: "type"
149
+ singleton_class.class_eval do
150
+ alias_method :_inheritance_column=, :inheritance_column=
151
+ private :_inheritance_column=
152
+ alias_method :inheritance_column=, :real_inheritance_column=
153
+ end
113
154
 
114
155
  self.protected_environments = ["production"]
115
- self.inheritance_column = "type"
156
+
116
157
  self.ignored_columns = [].freeze
117
158
 
118
- delegate :type_for_attribute, to: :class
159
+ delegate :type_for_attribute, :column_for_attribute, to: :class
119
160
 
120
161
  initialize_load_schema_monitor
121
162
  end
@@ -171,6 +212,21 @@ module ActiveRecord
171
212
  # the table name guess for an Invoice class becomes "myapp_invoices".
172
213
  # Invoice::Lineitem becomes "myapp_invoice_lineitems".
173
214
  #
215
+ # Active Model Naming's +model_name+ is the base name used to guess the
216
+ # table name. In case a custom Active Model Name is defined, it will be
217
+ # used for the table name as well:
218
+ #
219
+ # class PostRecord < ActiveRecord::Base
220
+ # class << self
221
+ # def model_name
222
+ # ActiveModel::Name.new(self, nil, "Post")
223
+ # end
224
+ # end
225
+ # end
226
+ #
227
+ # PostRecord.table_name
228
+ # # => "posts"
229
+ #
174
230
  # You can also set your own table name explicitly:
175
231
  #
176
232
  # class Mouse < ActiveRecord::Base
@@ -207,7 +263,7 @@ module ActiveRecord
207
263
  end
208
264
 
209
265
  # Computes the table name, (re)sets it internally, and returns it.
210
- def reset_table_name #:nodoc:
266
+ def reset_table_name # :nodoc:
211
267
  self.table_name = if abstract_class?
212
268
  superclass == Base ? nil : superclass.table_name
213
269
  elsif superclass.abstract_class?
@@ -217,12 +273,12 @@ module ActiveRecord
217
273
  end
218
274
  end
219
275
 
220
- def full_table_name_prefix #:nodoc:
221
- (parents.detect { |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
276
+ def full_table_name_prefix # :nodoc:
277
+ (module_parents.detect { |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
222
278
  end
223
279
 
224
- def full_table_name_suffix #:nodoc:
225
- (parents.detect { |p| p.respond_to?(:table_name_suffix) } || self).table_name_suffix
280
+ def full_table_name_suffix # :nodoc:
281
+ (module_parents.detect { |p| p.respond_to?(:table_name_suffix) } || self).table_name_suffix
226
282
  end
227
283
 
228
284
  # The array of names of environments where destructive actions should be prohibited. By default,
@@ -240,23 +296,8 @@ module ActiveRecord
240
296
  @protected_environments = environments.map(&:to_s)
241
297
  end
242
298
 
243
- # Defines the name of the table column which will store the class name on single-table
244
- # inheritance situations.
245
- #
246
- # The default inheritance column name is +type+, which means it's a
247
- # reserved word inside Active Record. To be able to use single-table
248
- # inheritance with another column name, or to use the column +type+ in
249
- # your own model for something else, you can set +inheritance_column+:
250
- #
251
- # self.inheritance_column = 'zoink'
252
- def inheritance_column
253
- (@inheritance_column ||= nil) || superclass.inheritance_column
254
- end
255
-
256
- # Sets the value of inheritance_column
257
- def inheritance_column=(value)
258
- @inheritance_column = value.to_s
259
- @explicit_inheritance_column = true
299
+ def real_inheritance_column=(value) # :nodoc:
300
+ self._inheritance_column = value.to_s
260
301
  end
261
302
 
262
303
  # The list of columns names the model should ignore. Ignored columns won't have attribute
@@ -271,19 +312,49 @@ module ActiveRecord
271
312
 
272
313
  # Sets the columns names the model should ignore. Ignored columns won't have attribute
273
314
  # accessors defined, and won't be referenced in SQL queries.
315
+ #
316
+ # A common usage pattern for this method is to ensure all references to an attribute
317
+ # have been removed and deployed, before a migration to drop the column from the database
318
+ # has been deployed and run. Using this two step approach to dropping columns ensures there
319
+ # is no code that raises errors due to having a cached schema in memory at the time the
320
+ # schema migration is run.
321
+ #
322
+ # For example, given a model where you want to drop the "category" attribute, first mark it
323
+ # as ignored:
324
+ #
325
+ # class Project < ActiveRecord::Base
326
+ # # schema:
327
+ # # id :bigint
328
+ # # name :string, limit: 255
329
+ # # category :string, limit: 255
330
+ #
331
+ # self.ignored_columns = [:category]
332
+ # end
333
+ #
334
+ # The schema still contains "category", but now the model omits it, so any meta-driven code or
335
+ # schema caching will not attempt to use the column:
336
+ #
337
+ # Project.columns_hash["category"] => nil
338
+ #
339
+ # You will get an error if accessing that attribute directly, so ensure all usages of the
340
+ # column are removed (automated tests can help you find any usages).
341
+ #
342
+ # user = Project.create!(name: "First Project")
343
+ # user.category # => raises NoMethodError
274
344
  def ignored_columns=(columns)
275
- @ignored_columns = columns.map(&:to_s)
345
+ reload_schema_from_cache
346
+ @ignored_columns = columns.map(&:to_s).freeze
276
347
  end
277
348
 
278
349
  def sequence_name
279
- if base_class == self
350
+ if base_class?
280
351
  @sequence_name ||= reset_sequence_name
281
352
  else
282
353
  (@sequence_name ||= nil) || base_class.sequence_name
283
354
  end
284
355
  end
285
356
 
286
- def reset_sequence_name #:nodoc:
357
+ def reset_sequence_name # :nodoc:
287
358
  @explicit_sequence_name = false
288
359
  @sequence_name = connection.default_sequence_name(table_name, primary_key)
289
360
  end
@@ -339,7 +410,7 @@ module ActiveRecord
339
410
 
340
411
  def columns
341
412
  load_schema
342
- @columns ||= columns_hash.values
413
+ @columns ||= columns_hash.values.freeze
343
414
  end
344
415
 
345
416
  def attribute_types # :nodoc:
@@ -364,6 +435,8 @@ module ActiveRecord
364
435
  # a string or a symbol.
365
436
  def type_for_attribute(attr_name, &block)
366
437
  attr_name = attr_name.to_s
438
+ attr_name = attribute_aliases[attr_name] || attr_name
439
+
367
440
  if block
368
441
  attribute_types.fetch(attr_name, &block)
369
442
  else
@@ -371,11 +444,31 @@ module ActiveRecord
371
444
  end
372
445
  end
373
446
 
447
+ # Returns the column object for the named attribute.
448
+ # Returns an +ActiveRecord::ConnectionAdapters::NullColumn+ if the
449
+ # named attribute does not exist.
450
+ #
451
+ # class Person < ActiveRecord::Base
452
+ # end
453
+ #
454
+ # person = Person.new
455
+ # person.column_for_attribute(:name) # the result depends on the ConnectionAdapter
456
+ # # => #<ActiveRecord::ConnectionAdapters::Column:0x007ff4ab083980 @name="name", @sql_type="varchar(255)", @null=true, ...>
457
+ #
458
+ # person.column_for_attribute(:nothing)
459
+ # # => #<ActiveRecord::ConnectionAdapters::NullColumn:0xXXX @name=nil, @sql_type=nil, @cast_type=#<Type::Value>, ...>
460
+ def column_for_attribute(name)
461
+ name = name.to_s
462
+ columns_hash.fetch(name) do
463
+ ConnectionAdapters::NullColumn.new(name)
464
+ end
465
+ end
466
+
374
467
  # Returns a hash where the keys are column names and the values are
375
468
  # default values when instantiating the Active Record object for this table.
376
469
  def column_defaults
377
470
  load_schema
378
- @column_defaults ||= _default_attributes.deep_dup.to_hash
471
+ @column_defaults ||= _default_attributes.deep_dup.to_hash.freeze
379
472
  end
380
473
 
381
474
  def _default_attributes # :nodoc:
@@ -385,7 +478,12 @@ module ActiveRecord
385
478
 
386
479
  # Returns an array of column names as strings.
387
480
  def column_names
388
- @column_names ||= columns.map(&:name)
481
+ @column_names ||= columns.map(&:name).freeze
482
+ end
483
+
484
+ def symbol_column_to_string(name_symbol) # :nodoc:
485
+ @symbol_column_to_string_name_hash ||= column_names.index_by(&:to_sym)
486
+ @symbol_column_to_string_name_hash[name_symbol]
389
487
  end
390
488
 
391
489
  # Returns an array of column objects where the primary id, all columns ending in "_id" or "_count",
@@ -394,9 +492,8 @@ module ActiveRecord
394
492
  @content_columns ||= columns.reject do |c|
395
493
  c.name == primary_key ||
396
494
  c.name == inheritance_column ||
397
- c.name.end_with?("_id") ||
398
- c.name.end_with?("_count")
399
- end
495
+ c.name.end_with?("_id", "_count")
496
+ end.freeze
400
497
  end
401
498
 
402
499
  # Resets all the cached information about columns, which will cause them
@@ -404,9 +501,9 @@ module ActiveRecord
404
501
  #
405
502
  # The most common usage pattern for this method is probably in a migration,
406
503
  # when just after creating a table you want to populate it with some default
407
- # values, eg:
504
+ # values, e.g.:
408
505
  #
409
- # class CreateJobLevels < ActiveRecord::Migration[5.0]
506
+ # class CreateJobLevels < ActiveRecord::Migration[7.0]
410
507
  # def up
411
508
  # create_table :job_levels do |t|
412
509
  # t.integer :id
@@ -435,13 +532,11 @@ module ActiveRecord
435
532
  end
436
533
 
437
534
  protected
438
-
439
535
  def initialize_load_schema_monitor
440
536
  @load_schema_monitor = Monitor.new
441
537
  end
442
538
 
443
539
  private
444
-
445
540
  def inherited(child_class)
446
541
  super
447
542
  child_class.initialize_load_schema_monitor
@@ -459,15 +554,26 @@ module ActiveRecord
459
554
  load_schema!
460
555
 
461
556
  @schema_loaded = true
557
+ rescue
558
+ reload_schema_from_cache # If the schema loading failed half way through, we must reset the state.
559
+ raise
462
560
  end
463
561
  end
464
562
 
465
563
  def load_schema!
466
- @columns_hash = connection.schema_cache.columns_hash(table_name).except(*ignored_columns)
564
+ unless table_name
565
+ raise ActiveRecord::TableNotSpecified, "#{self} has no table configured. Set one with #{self}.table_name="
566
+ end
567
+
568
+ columns_hash = connection.schema_cache.columns_hash(table_name)
569
+ columns_hash = columns_hash.except(*ignored_columns) unless ignored_columns.empty?
570
+ @columns_hash = columns_hash.freeze
467
571
  @columns_hash.each do |name, column|
572
+ type = connection.lookup_cast_type_from_column(column)
573
+ type = _convert_type_from_options(type)
468
574
  define_attribute(
469
575
  name,
470
- connection.lookup_cast_type_from_column(column),
576
+ type,
471
577
  default: column.default,
472
578
  user_provided_default: false
473
579
  )
@@ -477,43 +583,50 @@ module ActiveRecord
477
583
  def reload_schema_from_cache
478
584
  @arel_table = nil
479
585
  @column_names = nil
586
+ @symbol_column_to_string_name_hash = nil
480
587
  @attribute_types = nil
481
588
  @content_columns = nil
482
589
  @default_attributes = nil
483
590
  @column_defaults = nil
484
- @inheritance_column = nil unless defined?(@explicit_inheritance_column) && @explicit_inheritance_column
485
591
  @attributes_builder = nil
486
592
  @columns = nil
487
593
  @columns_hash = nil
488
594
  @schema_loaded = false
489
595
  @attribute_names = nil
490
596
  @yaml_encoder = nil
491
- direct_descendants.each do |descendant|
597
+ subclasses.each do |descendant|
492
598
  descendant.send(:reload_schema_from_cache)
493
599
  end
494
600
  end
495
601
 
496
602
  # Guesses the table name, but does not decorate it with prefix and suffix information.
497
- def undecorated_table_name(class_name = base_class.name)
498
- table_name = class_name.to_s.demodulize.underscore
603
+ def undecorated_table_name(model_name)
604
+ table_name = model_name.to_s.demodulize.underscore
499
605
  pluralize_table_names ? table_name.pluralize : table_name
500
606
  end
501
607
 
502
608
  # Computes and returns a table name according to default conventions.
503
609
  def compute_table_name
504
- base = base_class
505
- if self == base
610
+ if base_class?
506
611
  # Nested classes are prefixed with singular parent table name.
507
- if parent < Base && !parent.abstract_class?
508
- contained = parent.table_name
509
- contained = contained.singularize if parent.pluralize_table_names
612
+ if module_parent < Base && !module_parent.abstract_class?
613
+ contained = module_parent.table_name
614
+ contained = contained.singularize if module_parent.pluralize_table_names
510
615
  contained += "_"
511
616
  end
512
617
 
513
- "#{full_table_name_prefix}#{contained}#{undecorated_table_name(name)}#{full_table_name_suffix}"
618
+ "#{full_table_name_prefix}#{contained}#{undecorated_table_name(model_name)}#{full_table_name_suffix}"
514
619
  else
515
620
  # STI subclasses always use their superclass' table.
516
- base.table_name
621
+ base_class.table_name
622
+ end
623
+ end
624
+
625
+ def _convert_type_from_options(type)
626
+ if immutable_strings_by_default && type.respond_to?(:to_immutable_string)
627
+ type.to_immutable_string
628
+ else
629
+ type
517
630
  end
518
631
  end
519
632
  end
@@ -2,11 +2,10 @@
2
2
 
3
3
  require "active_support/core_ext/hash/except"
4
4
  require "active_support/core_ext/module/redefine_method"
5
- require "active_support/core_ext/object/try"
6
5
  require "active_support/core_ext/hash/indifferent_access"
7
6
 
8
7
  module ActiveRecord
9
- module NestedAttributes #:nodoc:
8
+ module NestedAttributes # :nodoc:
10
9
  class TooManyRecords < ActiveRecordError
11
10
  end
12
11
 
@@ -181,7 +180,7 @@ module ActiveRecord
181
180
  # member.posts.second.title # => '[UPDATED] other post'
182
181
  #
183
182
  # However, the above applies if the parent model is being updated as well.
184
- # For example, If you wanted to create a +member+ named _joe_ and wanted to
183
+ # For example, if you wanted to create a +member+ named _joe_ and wanted to
185
184
  # update the +posts+ at the same time, that would give an
186
185
  # ActiveRecord::RecordNotFound error.
187
186
  #
@@ -246,18 +245,19 @@ module ActiveRecord
246
245
  #
247
246
  # === Validating the presence of a parent model
248
247
  #
249
- # If you want to validate that a child record is associated with a parent
250
- # record, you can use the +validates_presence_of+ method and the +:inverse_of+
251
- # key as this example illustrates:
248
+ # The +belongs_to+ association validates the presence of the parent model
249
+ # by default. You can disable this behavior by specifying <code>optional: true</code>.
250
+ # This can be used, for example, when conditionally validating the presence
251
+ # of the parent model:
252
252
  #
253
- # class Member < ActiveRecord::Base
254
- # has_many :posts, inverse_of: :member
255
- # accepts_nested_attributes_for :posts
253
+ # class Veterinarian < ActiveRecord::Base
254
+ # has_many :patients, inverse_of: :veterinarian
255
+ # accepts_nested_attributes_for :patients
256
256
  # end
257
257
  #
258
- # class Post < ActiveRecord::Base
259
- # belongs_to :member, inverse_of: :posts
260
- # validates_presence_of :member
258
+ # class Patient < ActiveRecord::Base
259
+ # belongs_to :veterinarian, inverse_of: :patients, optional: true
260
+ # validates :veterinarian, presence: true, unless: -> { awaiting_intake }
261
261
  # end
262
262
  #
263
263
  # Note that if you do not specify the +:inverse_of+ option, then
@@ -289,7 +289,7 @@ module ActiveRecord
289
289
  # [:allow_destroy]
290
290
  # If true, destroys any members from the attributes hash with a
291
291
  # <tt>_destroy</tt> key and a value that evaluates to +true+
292
- # (eg. 1, '1', true, or 'true'). This option is off by default.
292
+ # (e.g. 1, '1', true, or 'true'). This option is off by default.
293
293
  # [:reject_if]
294
294
  # Allows you to specify a Proc or a Symbol pointing to a method
295
295
  # that checks whether a record should be built for a certain attribute
@@ -354,7 +354,6 @@ module ActiveRecord
354
354
  end
355
355
 
356
356
  private
357
-
358
357
  # Generates a writer method for this association. Serves as a point for
359
358
  # accessing the objects in the association. For example, this method
360
359
  # could generate the following:
@@ -386,7 +385,6 @@ module ActiveRecord
386
385
  end
387
386
 
388
387
  private
389
-
390
388
  # Attribute hash keys that should not be assigned as normal attributes.
391
389
  # These hash keys are nested attributes implementation details.
392
390
  UNASSIGNABLE_KEYS = %w( id _destroy )
@@ -426,7 +424,7 @@ module ActiveRecord
426
424
  existing_record.assign_attributes(assignable_attributes)
427
425
  association(association_name).initialize_attributes(existing_record)
428
426
  else
429
- method = "build_#{association_name}"
427
+ method = :"build_#{association_name}"
430
428
  if respond_to?(method)
431
429
  send(method, assignable_attributes)
432
430
  else
@@ -489,7 +487,7 @@ module ActiveRecord
489
487
  existing_records = if association.loaded?
490
488
  association.target
491
489
  else
492
- attribute_ids = attributes_collection.map { |a| a["id"] || a[:id] }.compact
490
+ attribute_ids = attributes_collection.filter_map { |a| a["id"] || a[:id] }
493
491
  attribute_ids.empty? ? [] : association.scope.where(association.klass.primary_key => attribute_ids)
494
492
  end
495
493
 
@@ -501,7 +499,7 @@ module ActiveRecord
501
499
 
502
500
  if attributes["id"].blank?
503
501
  unless reject_new_record?(association_name, attributes)
504
- association.build(attributes.except(*UNASSIGNABLE_KEYS))
502
+ association.reader.build(attributes.except(*UNASSIGNABLE_KEYS))
505
503
  end
506
504
  elsif existing_record = existing_records.detect { |record| record.id.to_s == attributes["id"].to_s }
507
505
  unless call_reject_if(association_name, attributes)
@@ -512,7 +510,7 @@ module ActiveRecord
512
510
  if target_record
513
511
  existing_record = target_record
514
512
  else
515
- association.add_to_target(existing_record, :skip_callbacks)
513
+ association.add_to_target(existing_record, skip_callbacks: true)
516
514
  end
517
515
 
518
516
  assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
@@ -26,23 +26,30 @@ module ActiveRecord
26
26
  end
27
27
 
28
28
  class << self
29
- def apply_to(klass) #:nodoc:
29
+ def apply_to(klass) # :nodoc:
30
30
  klasses.push(klass)
31
31
  yield
32
32
  ensure
33
33
  klasses.pop
34
34
  end
35
35
 
36
- def applied_to?(klass) #:nodoc:
36
+ def applied_to?(klass) # :nodoc:
37
37
  klasses.any? { |k| k >= klass }
38
38
  end
39
39
 
40
40
  private
41
41
  def klasses
42
- Thread.current[:no_touching_classes] ||= []
42
+ ActiveSupport::IsolatedExecutionState[:active_record_no_touching_classes] ||= []
43
43
  end
44
44
  end
45
45
 
46
+ # Returns +true+ if the class has +no_touching+ set, +false+ otherwise.
47
+ #
48
+ # Project.no_touching do
49
+ # Project.first.no_touching? # true
50
+ # Message.first.no_touching? # false
51
+ # end
52
+ #
46
53
  def no_touching?
47
54
  NoTouching.applied_to?(self.class)
48
55
  end
@@ -51,7 +58,7 @@ module ActiveRecord
51
58
  super unless no_touching?
52
59
  end
53
60
 
54
- def touch(*) # :nodoc:
61
+ def touch(*, **) # :nodoc:
55
62
  super unless no_touching?
56
63
  end
57
64
  end
@@ -38,10 +38,6 @@ module ActiveRecord
38
38
  false
39
39
  end
40
40
 
41
- def to_sql
42
- ""
43
- end
44
-
45
41
  def calculate(operation, _column_name)
46
42
  case operation
47
43
  when :count, :sum
@@ -60,9 +56,8 @@ module ActiveRecord
60
56
  end
61
57
 
62
58
  private
63
-
64
- def exec_queries
65
- @records = [].freeze
59
+ def exec_main_query(async: false)
60
+ [].freeze
66
61
  end
67
62
  end
68
63
  end