activerecord 5.0.6 → 6.0.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 (358) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +638 -2023
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +8 -6
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record/aggregations.rb +249 -246
  8. data/lib/active_record/association_relation.rb +24 -13
  9. data/lib/active_record/associations/alias_tracker.rb +24 -33
  10. data/lib/active_record/associations/association.rb +119 -56
  11. data/lib/active_record/associations/association_scope.rb +94 -94
  12. data/lib/active_record/associations/belongs_to_association.rb +58 -42
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  14. data/lib/active_record/associations/builder/association.rb +18 -25
  15. data/lib/active_record/associations/builder/belongs_to.rb +43 -54
  16. data/lib/active_record/associations/builder/collection_association.rb +7 -18
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +42 -61
  18. data/lib/active_record/associations/builder/has_many.rb +4 -0
  19. data/lib/active_record/associations/builder/has_one.rb +37 -1
  20. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  21. data/lib/active_record/associations/collection_association.rb +80 -252
  22. data/lib/active_record/associations/collection_proxy.rb +158 -121
  23. data/lib/active_record/associations/foreign_association.rb +9 -0
  24. data/lib/active_record/associations/has_many_association.rb +23 -29
  25. data/lib/active_record/associations/has_many_through_association.rb +58 -44
  26. data/lib/active_record/associations/has_one_association.rb +59 -54
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +38 -90
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
  31. data/lib/active_record/associations/join_dependency.rb +134 -176
  32. data/lib/active_record/associations/preloader/association.rb +84 -125
  33. data/lib/active_record/associations/preloader/through_association.rb +82 -75
  34. data/lib/active_record/associations/preloader.rb +90 -102
  35. data/lib/active_record/associations/singular_association.rb +12 -45
  36. data/lib/active_record/associations/through_association.rb +26 -14
  37. data/lib/active_record/associations.rb +1603 -1592
  38. data/lib/active_record/attribute_assignment.rb +54 -60
  39. data/lib/active_record/attribute_decorators.rb +38 -15
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +12 -7
  41. data/lib/active_record/attribute_methods/dirty.rb +179 -109
  42. data/lib/active_record/attribute_methods/primary_key.rb +86 -91
  43. data/lib/active_record/attribute_methods/query.rb +4 -3
  44. data/lib/active_record/attribute_methods/read.rb +21 -49
  45. data/lib/active_record/attribute_methods/serialization.rb +30 -7
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -64
  47. data/lib/active_record/attribute_methods/write.rb +35 -33
  48. data/lib/active_record/attribute_methods.rb +66 -106
  49. data/lib/active_record/attributes.rb +38 -24
  50. data/lib/active_record/autosave_association.rb +53 -32
  51. data/lib/active_record/base.rb +27 -24
  52. data/lib/active_record/callbacks.rb +63 -33
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +11 -11
  55. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +553 -321
  56. data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
  57. data/lib/active_record/connection_adapters/abstract/database_statements.rb +213 -94
  58. data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -28
  59. data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -75
  60. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  61. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -27
  62. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +207 -126
  63. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  64. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +369 -199
  65. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
  66. data/lib/active_record/connection_adapters/abstract_adapter.rb +363 -202
  67. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +405 -551
  68. data/lib/active_record/connection_adapters/column.rb +41 -13
  69. data/lib/active_record/connection_adapters/connection_specification.rb +172 -138
  70. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
  71. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  72. data/lib/active_record/connection_adapters/mysql/database_statements.rb +143 -49
  73. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -22
  74. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  75. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +50 -45
  76. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
  77. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  78. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  79. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
  80. data/lib/active_record/connection_adapters/mysql2_adapter.rb +49 -30
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +22 -7
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +60 -54
  83. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -10
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +4 -2
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -17
  94. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  98. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +31 -9
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +34 -30
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  102. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +9 -4
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +35 -32
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +380 -300
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +10 -6
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +382 -275
  116. data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +120 -0
  119. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  120. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +74 -19
  121. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
  122. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  125. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +254 -262
  126. data/lib/active_record/connection_adapters/statement_pool.rb +9 -7
  127. data/lib/active_record/connection_handling.rb +159 -40
  128. data/lib/active_record/core.rb +202 -162
  129. data/lib/active_record/counter_cache.rb +57 -28
  130. data/lib/active_record/database_configurations/database_config.rb +37 -0
  131. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  132. data/lib/active_record/database_configurations/url_config.rb +79 -0
  133. data/lib/active_record/database_configurations.rb +233 -0
  134. data/lib/active_record/define_callbacks.rb +22 -0
  135. data/lib/active_record/dynamic_matchers.rb +87 -86
  136. data/lib/active_record/enum.rb +60 -23
  137. data/lib/active_record/errors.rb +114 -18
  138. data/lib/active_record/explain.rb +4 -3
  139. data/lib/active_record/explain_registry.rb +3 -1
  140. data/lib/active_record/explain_subscriber.rb +9 -4
  141. data/lib/active_record/fixture_set/file.rb +13 -8
  142. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  143. data/lib/active_record/fixture_set/render_context.rb +17 -0
  144. data/lib/active_record/fixture_set/table_row.rb +153 -0
  145. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  146. data/lib/active_record/fixtures.rb +195 -502
  147. data/lib/active_record/gem_version.rb +4 -2
  148. data/lib/active_record/inheritance.rb +151 -97
  149. data/lib/active_record/insert_all.rb +179 -0
  150. data/lib/active_record/integration.rb +116 -25
  151. data/lib/active_record/internal_metadata.rb +15 -18
  152. data/lib/active_record/legacy_yaml_adapter.rb +4 -2
  153. data/lib/active_record/locking/optimistic.rb +78 -87
  154. data/lib/active_record/locking/pessimistic.rb +18 -6
  155. data/lib/active_record/log_subscriber.rb +48 -29
  156. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  157. data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
  158. data/lib/active_record/middleware/database_selector.rb +75 -0
  159. data/lib/active_record/migration/command_recorder.rb +143 -97
  160. data/lib/active_record/migration/compatibility.rb +174 -56
  161. data/lib/active_record/migration/join_table.rb +8 -6
  162. data/lib/active_record/migration.rb +367 -300
  163. data/lib/active_record/model_schema.rb +145 -139
  164. data/lib/active_record/nested_attributes.rb +214 -201
  165. data/lib/active_record/no_touching.rb +10 -1
  166. data/lib/active_record/null_relation.rb +13 -34
  167. data/lib/active_record/persistence.rb +442 -72
  168. data/lib/active_record/query_cache.rb +15 -14
  169. data/lib/active_record/querying.rb +36 -23
  170. data/lib/active_record/railtie.rb +128 -36
  171. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  172. data/lib/active_record/railties/console_sandbox.rb +2 -0
  173. data/lib/active_record/railties/controller_runtime.rb +34 -33
  174. data/lib/active_record/railties/databases.rake +309 -177
  175. data/lib/active_record/readonly_attributes.rb +5 -4
  176. data/lib/active_record/reflection.rb +211 -249
  177. data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
  178. data/lib/active_record/relation/batches.rb +99 -52
  179. data/lib/active_record/relation/calculations.rb +211 -172
  180. data/lib/active_record/relation/delegation.rb +67 -65
  181. data/lib/active_record/relation/finder_methods.rb +208 -247
  182. data/lib/active_record/relation/from_clause.rb +2 -8
  183. data/lib/active_record/relation/merger.rb +78 -61
  184. data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
  185. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  186. data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
  187. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  188. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  189. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  190. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  191. data/lib/active_record/relation/predicate_builder.rb +86 -104
  192. data/lib/active_record/relation/query_attribute.rb +33 -2
  193. data/lib/active_record/relation/query_methods.rb +458 -329
  194. data/lib/active_record/relation/record_fetch_warning.rb +5 -3
  195. data/lib/active_record/relation/spawn_methods.rb +8 -7
  196. data/lib/active_record/relation/where_clause.rb +111 -95
  197. data/lib/active_record/relation/where_clause_factory.rb +6 -11
  198. data/lib/active_record/relation.rb +429 -318
  199. data/lib/active_record/result.rb +69 -39
  200. data/lib/active_record/runtime_registry.rb +5 -3
  201. data/lib/active_record/sanitization.rb +83 -99
  202. data/lib/active_record/schema.rb +7 -14
  203. data/lib/active_record/schema_dumper.rb +71 -69
  204. data/lib/active_record/schema_migration.rb +15 -5
  205. data/lib/active_record/scoping/default.rb +93 -95
  206. data/lib/active_record/scoping/named.rb +45 -25
  207. data/lib/active_record/scoping.rb +20 -19
  208. data/lib/active_record/secure_token.rb +4 -2
  209. data/lib/active_record/serialization.rb +2 -0
  210. data/lib/active_record/statement_cache.rb +63 -28
  211. data/lib/active_record/store.rb +121 -41
  212. data/lib/active_record/suppressor.rb +4 -1
  213. data/lib/active_record/table_metadata.rb +26 -20
  214. data/lib/active_record/tasks/database_tasks.rb +276 -85
  215. data/lib/active_record/tasks/mysql_database_tasks.rb +54 -90
  216. data/lib/active_record/tasks/postgresql_database_tasks.rb +78 -47
  217. data/lib/active_record/tasks/sqlite_database_tasks.rb +34 -16
  218. data/lib/active_record/test_databases.rb +23 -0
  219. data/lib/active_record/test_fixtures.rb +224 -0
  220. data/lib/active_record/timestamp.rb +70 -35
  221. data/lib/active_record/touch_later.rb +7 -4
  222. data/lib/active_record/transactions.rb +133 -149
  223. data/lib/active_record/translation.rb +3 -1
  224. data/lib/active_record/type/adapter_specific_registry.rb +44 -45
  225. data/lib/active_record/type/date.rb +2 -0
  226. data/lib/active_record/type/date_time.rb +2 -0
  227. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  228. data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
  229. data/lib/active_record/type/internal/timezone.rb +2 -0
  230. data/lib/active_record/type/json.rb +30 -0
  231. data/lib/active_record/type/serialized.rb +16 -8
  232. data/lib/active_record/type/text.rb +11 -0
  233. data/lib/active_record/type/time.rb +2 -1
  234. data/lib/active_record/type/type_map.rb +13 -15
  235. data/lib/active_record/type/unsigned_integer.rb +17 -0
  236. data/lib/active_record/type.rb +23 -17
  237. data/lib/active_record/type_caster/connection.rb +17 -12
  238. data/lib/active_record/type_caster/map.rb +5 -4
  239. data/lib/active_record/type_caster.rb +4 -2
  240. data/lib/active_record/validations/absence.rb +2 -0
  241. data/lib/active_record/validations/associated.rb +3 -1
  242. data/lib/active_record/validations/length.rb +2 -0
  243. data/lib/active_record/validations/presence.rb +4 -2
  244. data/lib/active_record/validations/uniqueness.rb +29 -42
  245. data/lib/active_record/validations.rb +7 -4
  246. data/lib/active_record/version.rb +3 -1
  247. data/lib/active_record.rb +36 -22
  248. data/lib/arel/alias_predication.rb +9 -0
  249. data/lib/arel/attributes/attribute.rb +37 -0
  250. data/lib/arel/attributes.rb +22 -0
  251. data/lib/arel/collectors/bind.rb +24 -0
  252. data/lib/arel/collectors/composite.rb +31 -0
  253. data/lib/arel/collectors/plain_string.rb +20 -0
  254. data/lib/arel/collectors/sql_string.rb +20 -0
  255. data/lib/arel/collectors/substitute_binds.rb +28 -0
  256. data/lib/arel/crud.rb +42 -0
  257. data/lib/arel/delete_manager.rb +18 -0
  258. data/lib/arel/errors.rb +9 -0
  259. data/lib/arel/expressions.rb +29 -0
  260. data/lib/arel/factory_methods.rb +49 -0
  261. data/lib/arel/insert_manager.rb +49 -0
  262. data/lib/arel/math.rb +45 -0
  263. data/lib/arel/nodes/and.rb +32 -0
  264. data/lib/arel/nodes/ascending.rb +23 -0
  265. data/lib/arel/nodes/binary.rb +52 -0
  266. data/lib/arel/nodes/bind_param.rb +36 -0
  267. data/lib/arel/nodes/case.rb +55 -0
  268. data/lib/arel/nodes/casted.rb +50 -0
  269. data/lib/arel/nodes/comment.rb +29 -0
  270. data/lib/arel/nodes/count.rb +12 -0
  271. data/lib/arel/nodes/delete_statement.rb +45 -0
  272. data/lib/arel/nodes/descending.rb +23 -0
  273. data/lib/arel/nodes/equality.rb +18 -0
  274. data/lib/arel/nodes/extract.rb +24 -0
  275. data/lib/arel/nodes/false.rb +16 -0
  276. data/lib/arel/nodes/full_outer_join.rb +8 -0
  277. data/lib/arel/nodes/function.rb +44 -0
  278. data/lib/arel/nodes/grouping.rb +8 -0
  279. data/lib/arel/nodes/in.rb +8 -0
  280. data/lib/arel/nodes/infix_operation.rb +80 -0
  281. data/lib/arel/nodes/inner_join.rb +8 -0
  282. data/lib/arel/nodes/insert_statement.rb +37 -0
  283. data/lib/arel/nodes/join_source.rb +20 -0
  284. data/lib/arel/nodes/matches.rb +18 -0
  285. data/lib/arel/nodes/named_function.rb +23 -0
  286. data/lib/arel/nodes/node.rb +50 -0
  287. data/lib/arel/nodes/node_expression.rb +13 -0
  288. data/lib/arel/nodes/outer_join.rb +8 -0
  289. data/lib/arel/nodes/over.rb +15 -0
  290. data/lib/arel/nodes/regexp.rb +16 -0
  291. data/lib/arel/nodes/right_outer_join.rb +8 -0
  292. data/lib/arel/nodes/select_core.rb +67 -0
  293. data/lib/arel/nodes/select_statement.rb +41 -0
  294. data/lib/arel/nodes/sql_literal.rb +16 -0
  295. data/lib/arel/nodes/string_join.rb +11 -0
  296. data/lib/arel/nodes/table_alias.rb +27 -0
  297. data/lib/arel/nodes/terminal.rb +16 -0
  298. data/lib/arel/nodes/true.rb +16 -0
  299. data/lib/arel/nodes/unary.rb +45 -0
  300. data/lib/arel/nodes/unary_operation.rb +20 -0
  301. data/lib/arel/nodes/unqualified_column.rb +22 -0
  302. data/lib/arel/nodes/update_statement.rb +41 -0
  303. data/lib/arel/nodes/values_list.rb +9 -0
  304. data/lib/arel/nodes/window.rb +126 -0
  305. data/lib/arel/nodes/with.rb +11 -0
  306. data/lib/arel/nodes.rb +68 -0
  307. data/lib/arel/order_predications.rb +13 -0
  308. data/lib/arel/predications.rb +257 -0
  309. data/lib/arel/select_manager.rb +271 -0
  310. data/lib/arel/table.rb +110 -0
  311. data/lib/arel/tree_manager.rb +72 -0
  312. data/lib/arel/update_manager.rb +34 -0
  313. data/lib/arel/visitors/depth_first.rb +204 -0
  314. data/lib/arel/visitors/dot.rb +297 -0
  315. data/lib/arel/visitors/ibm_db.rb +34 -0
  316. data/lib/arel/visitors/informix.rb +62 -0
  317. data/lib/arel/visitors/mssql.rb +157 -0
  318. data/lib/arel/visitors/mysql.rb +83 -0
  319. data/lib/arel/visitors/oracle.rb +159 -0
  320. data/lib/arel/visitors/oracle12.rb +66 -0
  321. data/lib/arel/visitors/postgresql.rb +110 -0
  322. data/lib/arel/visitors/sqlite.rb +39 -0
  323. data/lib/arel/visitors/to_sql.rb +889 -0
  324. data/lib/arel/visitors/visitor.rb +46 -0
  325. data/lib/arel/visitors/where_sql.rb +23 -0
  326. data/lib/arel/visitors.rb +20 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +58 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  330. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -35
  332. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
  334. data/lib/rails/generators/active_record/migration.rb +17 -2
  335. data/lib/rails/generators/active_record/model/model_generator.rb +9 -29
  336. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  337. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  338. data/lib/rails/generators/active_record.rb +7 -5
  339. metadata +133 -50
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  342. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  343. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  344. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  347. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  348. data/lib/active_record/attribute.rb +0 -213
  349. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  350. data/lib/active_record/attribute_set/builder.rb +0 -130
  351. data/lib/active_record/attribute_set.rb +0 -110
  352. data/lib/active_record/collection_cache_key.rb +0 -50
  353. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  354. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  355. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  356. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  357. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  358. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,121 +1,122 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module DynamicMatchers #:nodoc:
3
- def respond_to?(name, include_private = false)
4
- if self == Base
5
- super
6
- else
5
+ private
6
+ def respond_to_missing?(name, _)
7
+ if self == Base
8
+ super
9
+ else
10
+ match = Method.match(self, name)
11
+ match && match.valid? || super
12
+ end
13
+ end
14
+
15
+ def method_missing(name, *arguments, &block)
7
16
  match = Method.match(self, name)
8
- match && match.valid? || super
17
+
18
+ if match && match.valid?
19
+ match.define
20
+ send(name, *arguments, &block)
21
+ else
22
+ super
23
+ end
9
24
  end
10
- end
11
25
 
12
- private
26
+ class Method
27
+ @matchers = []
13
28
 
14
- def method_missing(name, *arguments, &block)
15
- match = Method.match(self, name)
29
+ class << self
30
+ attr_reader :matchers
16
31
 
17
- if match && match.valid?
18
- match.define
19
- send(name, *arguments, &block)
20
- else
21
- super
22
- end
23
- end
32
+ def match(model, name)
33
+ klass = matchers.find { |k| k.pattern.match?(name) }
34
+ klass.new(model, name) if klass
35
+ end
24
36
 
25
- class Method
26
- @matchers = []
37
+ def pattern
38
+ @pattern ||= /\A#{prefix}_([_a-zA-Z]\w*)#{suffix}\Z/
39
+ end
27
40
 
28
- class << self
29
- attr_reader :matchers
41
+ def prefix
42
+ raise NotImplementedError
43
+ end
30
44
 
31
- def match(model, name)
32
- klass = matchers.find { |k| name =~ k.pattern }
33
- klass.new(model, name) if klass
45
+ def suffix
46
+ ""
47
+ end
34
48
  end
35
49
 
36
- def pattern
37
- @pattern ||= /\A#{prefix}_([_a-zA-Z]\w*)#{suffix}\Z/
38
- end
50
+ attr_reader :model, :name, :attribute_names
39
51
 
40
- def prefix
41
- raise NotImplementedError
52
+ def initialize(model, name)
53
+ @model = model
54
+ @name = name.to_s
55
+ @attribute_names = @name.match(self.class.pattern)[1].split("_and_")
56
+ @attribute_names.map! { |name| @model.attribute_aliases[name] || name }
42
57
  end
43
58
 
44
- def suffix
45
- ''
59
+ def valid?
60
+ attribute_names.all? { |name| model.columns_hash[name] || model.reflect_on_aggregation(name.to_sym) }
46
61
  end
47
- end
48
-
49
- attr_reader :model, :name, :attribute_names
50
62
 
51
- def initialize(model, name)
52
- @model = model
53
- @name = name.to_s
54
- @attribute_names = @name.match(self.class.pattern)[1].split('_and_')
55
- @attribute_names.map! { |n| @model.attribute_aliases[n] || n }
56
- end
63
+ def define
64
+ model.class_eval <<-CODE, __FILE__, __LINE__ + 1
65
+ def self.#{name}(#{signature})
66
+ #{body}
67
+ end
68
+ CODE
69
+ end
57
70
 
58
- def valid?
59
- attribute_names.all? { |name| model.columns_hash[name] || model.reflect_on_aggregation(name.to_sym) }
60
- end
71
+ private
61
72
 
62
- def define
63
- model.class_eval <<-CODE, __FILE__, __LINE__ + 1
64
- def self.#{name}(#{signature})
65
- #{body}
73
+ def body
74
+ "#{finder}(#{attributes_hash})"
66
75
  end
67
- CODE
68
- end
69
-
70
- private
71
-
72
- def body
73
- "#{finder}(#{attributes_hash})"
74
- end
75
76
 
76
- # The parameters in the signature may have reserved Ruby words, in order
77
- # to prevent errors, we start each param name with `_`.
78
- def signature
79
- attribute_names.map { |name| "_#{name}" }.join(', ')
80
- end
77
+ # The parameters in the signature may have reserved Ruby words, in order
78
+ # to prevent errors, we start each param name with `_`.
79
+ def signature
80
+ attribute_names.map { |name| "_#{name}" }.join(", ")
81
+ end
81
82
 
82
- # Given that the parameters starts with `_`, the finder needs to use the
83
- # same parameter name.
84
- def attributes_hash
85
- "{" + attribute_names.map { |name| ":#{name} => _#{name}" }.join(',') + "}"
86
- end
83
+ # Given that the parameters starts with `_`, the finder needs to use the
84
+ # same parameter name.
85
+ def attributes_hash
86
+ "{" + attribute_names.map { |name| ":#{name} => _#{name}" }.join(",") + "}"
87
+ end
87
88
 
88
- def finder
89
- raise NotImplementedError
89
+ def finder
90
+ raise NotImplementedError
91
+ end
90
92
  end
91
- end
92
93
 
93
- class FindBy < Method
94
- Method.matchers << self
94
+ class FindBy < Method
95
+ Method.matchers << self
95
96
 
96
- def self.prefix
97
- "find_by"
98
- end
97
+ def self.prefix
98
+ "find_by"
99
+ end
99
100
 
100
- def finder
101
- "find_by"
101
+ def finder
102
+ "find_by"
103
+ end
102
104
  end
103
- end
104
105
 
105
- class FindByBang < Method
106
- Method.matchers << self
106
+ class FindByBang < Method
107
+ Method.matchers << self
107
108
 
108
- def self.prefix
109
- "find_by"
110
- end
109
+ def self.prefix
110
+ "find_by"
111
+ end
111
112
 
112
- def self.suffix
113
- "!"
114
- end
113
+ def self.suffix
114
+ "!"
115
+ end
115
116
 
116
- def finder
117
- "find_by!"
117
+ def finder
118
+ "find_by!"
119
+ end
118
120
  end
119
- end
120
121
  end
121
122
  end
@@ -1,4 +1,6 @@
1
- require 'active_support/core_ext/object/deep_dup'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/deep_dup"
2
4
 
3
5
  module ActiveRecord
4
6
  # Declare an enum attribute where the values map to integers in the database,
@@ -29,7 +31,9 @@ module ActiveRecord
29
31
  # as well. With the above example:
30
32
  #
31
33
  # Conversation.active
34
+ # Conversation.not_active
32
35
  # Conversation.archived
36
+ # Conversation.not_archived
33
37
  #
34
38
  # Of course, you can also query them directly if the scopes don't fit your
35
39
  # needs:
@@ -95,8 +99,7 @@ module ActiveRecord
95
99
 
96
100
  module Enum
97
101
  def self.extended(base) # :nodoc:
98
- base.class_attribute(:defined_enums, instance_writer: false)
99
- base.defined_enums = {}
102
+ base.class_attribute(:defined_enums, instance_writer: false, default: {})
100
103
  end
101
104
 
102
105
  def inherited(base) # :nodoc:
@@ -140,23 +143,25 @@ module ActiveRecord
140
143
  end
141
144
  end
142
145
 
143
- protected
144
-
145
- attr_reader :name, :mapping, :subtype
146
+ private
147
+ attr_reader :name, :mapping, :subtype
146
148
  end
147
149
 
148
150
  def enum(definitions)
149
151
  klass = self
150
152
  enum_prefix = definitions.delete(:_prefix)
151
153
  enum_suffix = definitions.delete(:_suffix)
154
+ enum_scopes = definitions.delete(:_scopes)
152
155
  definitions.each do |name, values|
156
+ assert_valid_enum_definition_values(values)
153
157
  # statuses = { }
154
158
  enum_values = ActiveSupport::HashWithIndifferentAccess.new
155
- name = name.to_sym
159
+ name = name.to_s
156
160
 
157
161
  # def self.statuses() statuses end
158
- detect_enum_conflict!(name, name.to_s.pluralize, true)
159
- klass.singleton_class.send(:define_method, name.to_s.pluralize) { enum_values }
162
+ detect_enum_conflict!(name, name.pluralize, true)
163
+ singleton_class.define_method(name.pluralize) { enum_values }
164
+ defined_enums[name] = enum_values
160
165
 
161
166
  detect_enum_conflict!(name, name)
162
167
  detect_enum_conflict!(name, "#{name}=")
@@ -168,7 +173,7 @@ module ActiveRecord
168
173
 
169
174
  _enum_methods_module.module_eval do
170
175
  pairs = values.respond_to?(:each_pair) ? values.each_pair : values.each_with_index
171
- pairs.each do |value, i|
176
+ pairs.each do |label, value|
172
177
  if enum_prefix == true
173
178
  prefix = "#{name}_"
174
179
  elsif enum_prefix
@@ -180,23 +185,32 @@ module ActiveRecord
180
185
  suffix = "_#{enum_suffix}"
181
186
  end
182
187
 
183
- value_method_name = "#{prefix}#{value}#{suffix}"
184
- enum_values[value] = i
188
+ value_method_name = "#{prefix}#{label}#{suffix}"
189
+ enum_values[label] = value
190
+ label = label.to_s
185
191
 
186
- # def active?() status == 0 end
192
+ # def active?() status == "active" end
187
193
  klass.send(:detect_enum_conflict!, name, "#{value_method_name}?")
188
- define_method("#{value_method_name}?") { self[attr] == value.to_s }
194
+ define_method("#{value_method_name}?") { self[attr] == label }
189
195
 
190
- # def active!() update! status: :active end
196
+ # def active!() update!(status: 0) end
191
197
  klass.send(:detect_enum_conflict!, name, "#{value_method_name}!")
192
198
  define_method("#{value_method_name}!") { update!(attr => value) }
193
199
 
194
- # scope :active, -> { where status: 0 }
195
- klass.send(:detect_enum_conflict!, name, value_method_name, true)
196
- klass.scope value_method_name, -> { where(attr => value) }
200
+ # scope :active, -> { where(status: 0) }
201
+ # scope :not_active, -> { where.not(status: 0) }
202
+ if enum_scopes != false
203
+ klass.send(:detect_negative_condition!, value_method_name)
204
+
205
+ klass.send(:detect_enum_conflict!, name, value_method_name, true)
206
+ klass.scope value_method_name, -> { where(attr => value) }
207
+
208
+ klass.send(:detect_enum_conflict!, name, "not_#{value_method_name}", true)
209
+ klass.scope "not_#{value_method_name}", -> { where.not(attr => value) }
210
+ end
197
211
  end
198
212
  end
199
- defined_enums[name.to_s] = enum_values
213
+ enum_values.freeze
200
214
  end
201
215
  end
202
216
 
@@ -209,29 +223,52 @@ module ActiveRecord
209
223
  end
210
224
  end
211
225
 
226
+ def assert_valid_enum_definition_values(values)
227
+ unless values.is_a?(Hash) || values.all? { |v| v.is_a?(Symbol) } || values.all? { |v| v.is_a?(String) }
228
+ error_message = <<~MSG
229
+ Enum values #{values} must be either a hash, an array of symbols, or an array of strings.
230
+ MSG
231
+ raise ArgumentError, error_message
232
+ end
233
+
234
+ if values.is_a?(Hash) && values.keys.any?(&:blank?) || values.is_a?(Array) && values.any?(&:blank?)
235
+ raise ArgumentError, "Enum label name must not be blank."
236
+ end
237
+ end
238
+
212
239
  ENUM_CONFLICT_MESSAGE = \
213
240
  "You tried to define an enum named \"%{enum}\" on the model \"%{klass}\", but " \
214
241
  "this will generate a %{type} method \"%{method}\", which is already defined " \
215
242
  "by %{source}."
243
+ private_constant :ENUM_CONFLICT_MESSAGE
216
244
 
217
245
  def detect_enum_conflict!(enum_name, method_name, klass_method = false)
218
246
  if klass_method && dangerous_class_method?(method_name)
219
- raise_conflict_error(enum_name, method_name, type: 'class')
247
+ raise_conflict_error(enum_name, method_name, type: "class")
248
+ elsif klass_method && method_defined_within?(method_name, Relation)
249
+ raise_conflict_error(enum_name, method_name, type: "class", source: Relation.name)
220
250
  elsif !klass_method && dangerous_attribute_method?(method_name)
221
251
  raise_conflict_error(enum_name, method_name)
222
252
  elsif !klass_method && method_defined_within?(method_name, _enum_methods_module, Module)
223
- raise_conflict_error(enum_name, method_name, source: 'another enum')
253
+ raise_conflict_error(enum_name, method_name, source: "another enum")
224
254
  end
225
255
  end
226
256
 
227
- def raise_conflict_error(enum_name, method_name, type: 'instance', source: 'Active Record')
257
+ def raise_conflict_error(enum_name, method_name, type: "instance", source: "Active Record")
228
258
  raise ArgumentError, ENUM_CONFLICT_MESSAGE % {
229
259
  enum: enum_name,
230
- klass: self.name,
260
+ klass: name,
231
261
  type: type,
232
262
  method: method_name,
233
263
  source: source
234
264
  }
235
265
  end
266
+
267
+ def detect_negative_condition!(method_name)
268
+ if method_name.start_with?("not_") && logger
269
+ logger.warn "An enum element in #{self.name} uses the prefix 'not_'." \
270
+ " This will cause a conflict with auto generated negative scopes."
271
+ end
272
+ end
236
273
  end
237
274
  end
@@ -1,5 +1,6 @@
1
- module ActiveRecord
1
+ # frozen_string_literal: true
2
2
 
3
+ module ActiveRecord
3
4
  # = Active Record Errors
4
5
  #
5
6
  # Generic Active Record exception class.
@@ -44,10 +45,14 @@ module ActiveRecord
44
45
 
45
46
  # Raised when connection to the database could not been established (for example when
46
47
  # {ActiveRecord::Base.connection=}[rdoc-ref:ConnectionHandling#connection]
47
- # is given a nil object).
48
+ # is given a +nil+ object).
48
49
  class ConnectionNotEstablished < ActiveRecordError
49
50
  end
50
51
 
52
+ # Raised when a write to the database is attempted on a read only connection.
53
+ class ReadOnlyError < ActiveRecordError
54
+ end
55
+
51
56
  # Raised when Active Record cannot find a record by given id or set of ids.
52
57
  class RecordNotFound < ActiveRecordError
53
58
  attr_reader :model, :primary_key, :id
@@ -63,7 +68,7 @@ module ActiveRecord
63
68
 
64
69
  # Raised by {ActiveRecord::Base#save!}[rdoc-ref:Persistence#save!] and
65
70
  # {ActiveRecord::Base.create!}[rdoc-ref:Persistence::ClassMethods#create!]
66
- # methods when a record is invalid and can not be saved.
71
+ # methods when a record is invalid and cannot be saved.
67
72
  class RecordNotSaved < ActiveRecordError
68
73
  attr_reader :record
69
74
 
@@ -96,20 +101,13 @@ module ActiveRecord
96
101
  #
97
102
  # Wraps the underlying database error as +cause+.
98
103
  class StatementInvalid < ActiveRecordError
99
-
100
- def initialize(message = nil, original_exception = nil)
101
- if original_exception
102
- ActiveSupport::Deprecation.warn("Passing #original_exception is deprecated and has no effect. " \
103
- "Exceptions will automatically capture the original exception.", caller)
104
- end
105
-
104
+ def initialize(message = nil, sql: nil, binds: nil)
106
105
  super(message || $!.try(:message))
106
+ @sql = sql
107
+ @binds = binds
107
108
  end
108
109
 
109
- def original_exception
110
- ActiveSupport::Deprecation.warn("#original_exception is deprecated. Use #cause instead.", caller)
111
- cause
112
- end
110
+ attr_reader :sql, :binds
113
111
  end
114
112
 
115
113
  # Defunct wrapper class kept for compatibility.
@@ -117,18 +115,60 @@ module ActiveRecord
117
115
  class WrappedDatabaseException < StatementInvalid
118
116
  end
119
117
 
120
- # Raised when a record cannot be inserted because it would violate a uniqueness constraint.
118
+ # Raised when a record cannot be inserted or updated because it would violate a uniqueness constraint.
121
119
  class RecordNotUnique < WrappedDatabaseException
122
120
  end
123
121
 
124
- # Raised when a record cannot be inserted or updated because it references a non-existent record.
122
+ # Raised when a record cannot be inserted or updated because it references a non-existent record,
123
+ # or when a record cannot be deleted because a parent record references it.
125
124
  class InvalidForeignKey < WrappedDatabaseException
126
125
  end
127
126
 
127
+ # Raised when a foreign key constraint cannot be added because the column type does not match the referenced column type.
128
+ class MismatchedForeignKey < StatementInvalid
129
+ def initialize(
130
+ message: nil,
131
+ sql: nil,
132
+ binds: nil,
133
+ table: nil,
134
+ foreign_key: nil,
135
+ target_table: nil,
136
+ primary_key: nil,
137
+ primary_key_column: nil
138
+ )
139
+ if table
140
+ type = primary_key_column.bigint? ? :bigint : primary_key_column.type
141
+ msg = <<~EOM.squish
142
+ Column `#{foreign_key}` on table `#{table}` does not match column `#{primary_key}` on `#{target_table}`,
143
+ which has type `#{primary_key_column.sql_type}`.
144
+ To resolve this issue, change the type of the `#{foreign_key}` column on `#{table}` to be :#{type}.
145
+ (For example `t.#{type} :#{foreign_key}`).
146
+ EOM
147
+ else
148
+ msg = <<~EOM.squish
149
+ There is a mismatch between the foreign key and primary key column types.
150
+ Verify that the foreign key column type and the primary key of the associated table match types.
151
+ EOM
152
+ end
153
+ if message
154
+ msg << "\nOriginal message: #{message}"
155
+ end
156
+ super(msg, sql: sql, binds: binds)
157
+ end
158
+ end
159
+
160
+ # Raised when a record cannot be inserted or updated because it would violate a not null constraint.
161
+ class NotNullViolation < StatementInvalid
162
+ end
163
+
128
164
  # Raised when a record cannot be inserted or updated because a value too long for a column type.
129
165
  class ValueTooLong < StatementInvalid
130
166
  end
131
167
 
168
+ # Raised when values that executed are out of range.
169
+ class RangeError < StatementInvalid
170
+ end
171
+
132
172
  # Raised when number of bind variables in statement given to +:condition+ key
133
173
  # (for example, when using {ActiveRecord::Base.find}[rdoc-ref:FinderMethods#find] method)
134
174
  # does not match number of expected values supplied.
@@ -143,7 +183,7 @@ module ActiveRecord
143
183
  class NoDatabaseError < StatementInvalid
144
184
  end
145
185
 
146
- # Raised when Postgres returns 'cached plan must not change result type' and
186
+ # Raised when PostgreSQL returns 'cached plan must not change result type' and
147
187
  # we cannot retry gracefully (e.g. inside a transaction)
148
188
  class PreparedStatementCacheExpired < StatementInvalid
149
189
  end
@@ -166,7 +206,6 @@ module ActiveRecord
166
206
  super("Stale object error.")
167
207
  end
168
208
  end
169
-
170
209
  end
171
210
 
172
211
  # Raised when association is being configured improperly or user tries to use
@@ -285,8 +324,65 @@ module ActiveRecord
285
324
  class TransactionIsolationError < ActiveRecordError
286
325
  end
287
326
 
327
+ # TransactionRollbackError will be raised when a transaction is rolled
328
+ # back by the database due to a serialization failure or a deadlock.
329
+ #
330
+ # See the following:
331
+ #
332
+ # * https://www.postgresql.org/docs/current/static/transaction-iso.html
333
+ # * https://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html#error_er_lock_deadlock
334
+ class TransactionRollbackError < StatementInvalid
335
+ end
336
+
337
+ # SerializationFailure will be raised when a transaction is rolled
338
+ # back by the database due to a serialization failure.
339
+ class SerializationFailure < TransactionRollbackError
340
+ end
341
+
342
+ # Deadlocked will be raised when a transaction is rolled
343
+ # back by the database when a deadlock is encountered.
344
+ class Deadlocked < TransactionRollbackError
345
+ end
346
+
288
347
  # IrreversibleOrderError is raised when a relation's order is too complex for
289
348
  # +reverse_order+ to automatically reverse.
290
349
  class IrreversibleOrderError < ActiveRecordError
291
350
  end
351
+
352
+ # LockWaitTimeout will be raised when lock wait timeout exceeded.
353
+ class LockWaitTimeout < StatementInvalid
354
+ end
355
+
356
+ # StatementTimeout will be raised when statement timeout exceeded.
357
+ class StatementTimeout < StatementInvalid
358
+ end
359
+
360
+ # QueryCanceled will be raised when canceling statement due to user request.
361
+ class QueryCanceled < StatementInvalid
362
+ end
363
+
364
+ # UnknownAttributeReference is raised when an unknown and potentially unsafe
365
+ # value is passed to a query method when allow_unsafe_raw_sql is set to
366
+ # :disabled. For example, passing a non column name value to a relation's
367
+ # #order method might cause this exception.
368
+ #
369
+ # When working around this exception, caution should be taken to avoid SQL
370
+ # injection vulnerabilities when passing user-provided values to query
371
+ # methods. Known-safe values can be passed to query methods by wrapping them
372
+ # in Arel.sql.
373
+ #
374
+ # For example, with allow_unsafe_raw_sql set to :disabled, the following
375
+ # code would raise this exception:
376
+ #
377
+ # Post.order("length(title)").first
378
+ #
379
+ # The desired result can be accomplished by wrapping the known-safe string
380
+ # in Arel.sql:
381
+ #
382
+ # Post.order(Arel.sql("length(title)")).first
383
+ #
384
+ # Again, such a workaround should *not* be used when passing user-provided
385
+ # values, such as request parameters or model attributes to query methods.
386
+ class UnknownAttributeReference < ActiveRecordError
387
+ end
292
388
  end
@@ -1,5 +1,6 @@
1
- require 'active_support/lazy_load_hooks'
2
- require 'active_record/explain_registry'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/explain_registry"
3
4
 
4
5
  module ActiveRecord
5
6
  module Explain
@@ -17,7 +18,7 @@ module ActiveRecord
17
18
  # Returns a formatted string ready to be logged.
18
19
  def exec_explain(queries) # :nodoc:
19
20
  str = queries.map do |sql, binds|
20
- msg = "EXPLAIN for: #{sql}"
21
+ msg = +"EXPLAIN for: #{sql}"
21
22
  unless binds.empty?
22
23
  msg << " "
23
24
  msg << binds.map { |attr| render_bind(attr) }.inspect
@@ -1,4 +1,6 @@
1
- require 'active_support/per_thread_registry'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/per_thread_registry"
2
4
 
3
5
  module ActiveRecord
4
6
  # This is a thread locals registry for EXPLAIN. For example
@@ -1,5 +1,7 @@
1
- require 'active_support/notifications'
2
- require 'active_record/explain_registry'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/notifications"
4
+ require "active_record/explain_registry"
3
5
 
4
6
  module ActiveRecord
5
7
  class ExplainSubscriber # :nodoc:
@@ -18,10 +20,13 @@ module ActiveRecord
18
20
  #
19
21
  # On the other hand, we want to monitor the performance of our real database
20
22
  # queries, not the performance of the access to the query cache.
21
- IGNORED_PAYLOADS = %w(SCHEMA EXPLAIN CACHE)
23
+ IGNORED_PAYLOADS = %w(SCHEMA EXPLAIN)
22
24
  EXPLAINED_SQLS = /\A\s*(with|select|update|delete|insert)\b/i
23
25
  def ignore_payload?(payload)
24
- payload[:exception] || IGNORED_PAYLOADS.include?(payload[:name]) || payload[:sql] !~ EXPLAINED_SQLS
26
+ payload[:exception] ||
27
+ payload[:cached] ||
28
+ IGNORED_PAYLOADS.include?(payload[:name]) ||
29
+ payload[:sql] !~ EXPLAINED_SQLS
25
30
  end
26
31
 
27
32
  ActiveSupport::Notifications.subscribe("sql.active_record", new)
@@ -1,5 +1,7 @@
1
- require 'erb'
2
- require 'yaml'
1
+ # frozen_string_literal: true
2
+
3
+ require "erb"
4
+ require "yaml"
3
5
 
4
6
  module ActiveRecord
5
7
  class FixtureSet
@@ -24,21 +26,21 @@ module ActiveRecord
24
26
  end
25
27
 
26
28
  def model_class
27
- config_row['model_class']
29
+ config_row["model_class"]
28
30
  end
29
31
 
30
32
  private
31
33
  def rows
32
- @rows ||= raw_rows.reject { |fixture_name, _| fixture_name == '_fixture' }
34
+ @rows ||= raw_rows.reject { |fixture_name, _| fixture_name == "_fixture" }
33
35
  end
34
36
 
35
37
  def config_row
36
38
  @config_row ||= begin
37
- row = raw_rows.find { |fixture_name, _| fixture_name == '_fixture' }
39
+ row = raw_rows.find { |fixture_name, _| fixture_name == "_fixture" }
38
40
  if row
39
41
  row.last
40
42
  else
41
- {'model_class': nil}
43
+ { 'model_class': nil }
42
44
  end
43
45
  end
44
46
  end
@@ -66,10 +68,13 @@ module ActiveRecord
66
68
  # Validate our unmarshalled data.
67
69
  def validate(data)
68
70
  unless Hash === data || YAML::Omap === data
69
- raise Fixture::FormatError, 'fixture is not a hash'
71
+ raise Fixture::FormatError, "fixture is not a hash: #{@file}"
70
72
  end
71
73
 
72
- raise Fixture::FormatError unless data.all? { |name, row| Hash === row }
74
+ invalid = data.reject { |_, row| Hash === row }
75
+ if invalid.any?
76
+ raise Fixture::FormatError, "fixture key is not a hash: #{@file}, keys: #{invalid.keys.inspect}"
77
+ end
73
78
  data
74
79
  end
75
80
  end