activerecord 4.2.9 → 6.1.4.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 (374) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +964 -1382
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +15 -14
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/aggregations.rb +266 -251
  8. data/lib/active_record/association_relation.rb +40 -15
  9. data/lib/active_record/associations/alias_tracker.rb +40 -43
  10. data/lib/active_record/associations/association.rb +162 -69
  11. data/lib/active_record/associations/association_scope.rb +105 -130
  12. data/lib/active_record/associations/belongs_to_association.rb +83 -65
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
  14. data/lib/active_record/associations/builder/association.rb +57 -43
  15. data/lib/active_record/associations/builder/belongs_to.rb +74 -57
  16. data/lib/active_record/associations/builder/collection_association.rb +15 -37
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +49 -66
  18. data/lib/active_record/associations/builder/has_many.rb +13 -5
  19. data/lib/active_record/associations/builder/has_one.rb +44 -6
  20. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  21. data/lib/active_record/associations/collection_association.rb +148 -287
  22. data/lib/active_record/associations/collection_proxy.rb +252 -150
  23. data/lib/active_record/associations/foreign_association.rb +23 -1
  24. data/lib/active_record/associations/has_many_association.rb +56 -98
  25. data/lib/active_record/associations/has_many_through_association.rb +68 -89
  26. data/lib/active_record/associations/has_one_association.rb +73 -47
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +54 -81
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  31. data/lib/active_record/associations/join_dependency.rb +174 -169
  32. data/lib/active_record/associations/preloader/association.rb +108 -115
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +97 -94
  35. data/lib/active_record/associations/singular_association.rb +18 -39
  36. data/lib/active_record/associations/through_association.rb +39 -19
  37. data/lib/active_record/associations.rb +1845 -1598
  38. data/lib/active_record/attribute_assignment.rb +59 -185
  39. data/lib/active_record/attribute_methods/before_type_cast.rb +18 -10
  40. data/lib/active_record/attribute_methods/dirty.rb +168 -148
  41. data/lib/active_record/attribute_methods/primary_key.rb +93 -83
  42. data/lib/active_record/attribute_methods/query.rb +8 -10
  43. data/lib/active_record/attribute_methods/read.rb +19 -79
  44. data/lib/active_record/attribute_methods/serialization.rb +49 -24
  45. data/lib/active_record/attribute_methods/time_zone_conversion.rb +55 -36
  46. data/lib/active_record/attribute_methods/write.rb +24 -55
  47. data/lib/active_record/attribute_methods.rb +149 -154
  48. data/lib/active_record/attributes.rb +234 -78
  49. data/lib/active_record/autosave_association.rb +133 -60
  50. data/lib/active_record/base.rb +46 -46
  51. data/lib/active_record/callbacks.rb +234 -79
  52. data/lib/active_record/coders/json.rb +3 -1
  53. data/lib/active_record/coders/yaml_column.rb +34 -13
  54. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +887 -323
  55. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -41
  56. data/lib/active_record/connection_adapters/abstract/database_statements.rb +292 -124
  57. data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -24
  58. data/lib/active_record/connection_adapters/abstract/quoting.rb +177 -60
  59. data/lib/active_record/connection_adapters/abstract/savepoints.rb +8 -6
  60. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +157 -93
  61. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +473 -255
  62. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  63. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +869 -286
  64. data/lib/active_record/connection_adapters/abstract/transaction.rb +257 -91
  65. data/lib/active_record/connection_adapters/abstract_adapter.rb +483 -230
  66. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +557 -640
  67. data/lib/active_record/connection_adapters/column.rb +67 -40
  68. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  69. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  70. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  71. data/lib/active_record/connection_adapters/mysql/database_statements.rb +194 -0
  72. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  73. data/lib/active_record/connection_adapters/mysql/quoting.rb +96 -0
  74. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +97 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +103 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +91 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
  78. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
  79. data/lib/active_record/connection_adapters/mysql2_adapter.rb +80 -192
  80. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  81. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +44 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +75 -160
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +49 -58
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +4 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +8 -6
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -19
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -20
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  98. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  101. data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +70 -34
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  109. data/lib/active_record/connection_adapters/postgresql/oid.rb +25 -25
  110. data/lib/active_record/connection_adapters/postgresql/quoting.rb +145 -48
  111. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  112. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  114. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
  115. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +496 -298
  116. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +44 -0
  117. data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
  118. data/lib/active_record/connection_adapters/postgresql_adapter.rb +588 -375
  119. data/lib/active_record/connection_adapters/schema_cache.rb +167 -29
  120. data/lib/active_record/connection_adapters/sql_type_metadata.rb +45 -0
  121. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
  122. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  123. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +21 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  126. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  127. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
  128. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +322 -373
  129. data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
  130. data/lib/active_record/connection_adapters.rb +52 -0
  131. data/lib/active_record/connection_handling.rb +314 -41
  132. data/lib/active_record/core.rb +458 -241
  133. data/lib/active_record/counter_cache.rb +70 -49
  134. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  135. data/lib/active_record/database_configurations/database_config.rb +80 -0
  136. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  137. data/lib/active_record/database_configurations/url_config.rb +53 -0
  138. data/lib/active_record/database_configurations.rb +272 -0
  139. data/lib/active_record/delegated_type.rb +209 -0
  140. data/lib/active_record/destroy_association_async_job.rb +36 -0
  141. data/lib/active_record/dynamic_matchers.rb +87 -106
  142. data/lib/active_record/enum.rb +211 -92
  143. data/lib/active_record/errors.rb +224 -54
  144. data/lib/active_record/explain.rb +27 -11
  145. data/lib/active_record/explain_registry.rb +4 -2
  146. data/lib/active_record/explain_subscriber.rb +10 -5
  147. data/lib/active_record/fixture_set/file.rb +33 -14
  148. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  149. data/lib/active_record/fixture_set/render_context.rb +17 -0
  150. data/lib/active_record/fixture_set/table_row.rb +152 -0
  151. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  152. data/lib/active_record/fixtures.rb +275 -500
  153. data/lib/active_record/gem_version.rb +6 -4
  154. data/lib/active_record/inheritance.rb +175 -110
  155. data/lib/active_record/insert_all.rb +212 -0
  156. data/lib/active_record/integration.rb +121 -29
  157. data/lib/active_record/internal_metadata.rb +62 -0
  158. data/lib/active_record/legacy_yaml_adapter.rb +27 -5
  159. data/lib/active_record/locale/en.yml +3 -2
  160. data/lib/active_record/locking/optimistic.rb +98 -92
  161. data/lib/active_record/locking/pessimistic.rb +22 -6
  162. data/lib/active_record/log_subscriber.rb +93 -31
  163. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  164. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  165. data/lib/active_record/middleware/database_selector.rb +77 -0
  166. data/lib/active_record/migration/command_recorder.rb +185 -90
  167. data/lib/active_record/migration/compatibility.rb +295 -0
  168. data/lib/active_record/migration/join_table.rb +8 -7
  169. data/lib/active_record/migration.rb +673 -325
  170. data/lib/active_record/model_schema.rb +418 -113
  171. data/lib/active_record/nested_attributes.rb +263 -224
  172. data/lib/active_record/no_touching.rb +15 -2
  173. data/lib/active_record/null_relation.rb +24 -38
  174. data/lib/active_record/persistence.rb +572 -136
  175. data/lib/active_record/query_cache.rb +29 -23
  176. data/lib/active_record/querying.rb +50 -31
  177. data/lib/active_record/railtie.rb +170 -51
  178. data/lib/active_record/railties/console_sandbox.rb +3 -3
  179. data/lib/active_record/railties/controller_runtime.rb +34 -33
  180. data/lib/active_record/railties/databases.rake +523 -199
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +454 -291
  183. data/lib/active_record/relation/batches/batch_enumerator.rb +85 -0
  184. data/lib/active_record/relation/batches.rb +217 -59
  185. data/lib/active_record/relation/calculations.rb +324 -249
  186. data/lib/active_record/relation/delegation.rb +76 -84
  187. data/lib/active_record/relation/finder_methods.rb +316 -242
  188. data/lib/active_record/relation/from_clause.rb +30 -0
  189. data/lib/active_record/relation/merger.rb +95 -103
  190. data/lib/active_record/relation/predicate_builder/array_handler.rb +26 -26
  191. data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
  192. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  193. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +57 -0
  194. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  195. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  196. data/lib/active_record/relation/predicate_builder.rb +136 -122
  197. data/lib/active_record/relation/query_attribute.rb +50 -0
  198. data/lib/active_record/relation/query_methods.rb +757 -413
  199. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  200. data/lib/active_record/relation/spawn_methods.rb +18 -20
  201. data/lib/active_record/relation/where_clause.rb +239 -0
  202. data/lib/active_record/relation.rb +554 -343
  203. data/lib/active_record/result.rb +91 -47
  204. data/lib/active_record/runtime_registry.rb +6 -4
  205. data/lib/active_record/sanitization.rb +134 -122
  206. data/lib/active_record/schema.rb +21 -24
  207. data/lib/active_record/schema_dumper.rb +141 -92
  208. data/lib/active_record/schema_migration.rb +24 -23
  209. data/lib/active_record/scoping/default.rb +96 -83
  210. data/lib/active_record/scoping/named.rb +78 -36
  211. data/lib/active_record/scoping.rb +45 -27
  212. data/lib/active_record/secure_token.rb +48 -0
  213. data/lib/active_record/serialization.rb +8 -6
  214. data/lib/active_record/signed_id.rb +116 -0
  215. data/lib/active_record/statement_cache.rb +89 -36
  216. data/lib/active_record/store.rb +128 -43
  217. data/lib/active_record/suppressor.rb +61 -0
  218. data/lib/active_record/table_metadata.rb +81 -0
  219. data/lib/active_record/tasks/database_tasks.rb +364 -130
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +67 -113
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +86 -49
  222. data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -19
  223. data/lib/active_record/test_databases.rb +24 -0
  224. data/lib/active_record/test_fixtures.rb +287 -0
  225. data/lib/active_record/timestamp.rb +86 -43
  226. data/lib/active_record/touch_later.rb +65 -0
  227. data/lib/active_record/transactions.rb +182 -163
  228. data/lib/active_record/translation.rb +3 -1
  229. data/lib/active_record/type/adapter_specific_registry.rb +126 -0
  230. data/lib/active_record/type/date.rb +4 -45
  231. data/lib/active_record/type/date_time.rb +4 -49
  232. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  233. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  234. data/lib/active_record/type/internal/timezone.rb +17 -0
  235. data/lib/active_record/type/json.rb +30 -0
  236. data/lib/active_record/type/serialized.rb +27 -15
  237. data/lib/active_record/type/text.rb +2 -2
  238. data/lib/active_record/type/time.rb +21 -16
  239. data/lib/active_record/type/type_map.rb +16 -19
  240. data/lib/active_record/type/unsigned_integer.rb +9 -8
  241. data/lib/active_record/type.rb +84 -23
  242. data/lib/active_record/type_caster/connection.rb +33 -0
  243. data/lib/active_record/type_caster/map.rb +23 -0
  244. data/lib/active_record/type_caster.rb +9 -0
  245. data/lib/active_record/validations/absence.rb +25 -0
  246. data/lib/active_record/validations/associated.rb +12 -4
  247. data/lib/active_record/validations/length.rb +26 -0
  248. data/lib/active_record/validations/numericality.rb +35 -0
  249. data/lib/active_record/validations/presence.rb +14 -13
  250. data/lib/active_record/validations/uniqueness.rb +63 -56
  251. data/lib/active_record/validations.rb +39 -35
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/active_record.rb +42 -29
  254. data/lib/arel/alias_predication.rb +9 -0
  255. data/lib/arel/attributes/attribute.rb +41 -0
  256. data/lib/arel/collectors/bind.rb +29 -0
  257. data/lib/arel/collectors/composite.rb +39 -0
  258. data/lib/arel/collectors/plain_string.rb +20 -0
  259. data/lib/arel/collectors/sql_string.rb +27 -0
  260. data/lib/arel/collectors/substitute_binds.rb +35 -0
  261. data/lib/arel/crud.rb +42 -0
  262. data/lib/arel/delete_manager.rb +18 -0
  263. data/lib/arel/errors.rb +9 -0
  264. data/lib/arel/expressions.rb +29 -0
  265. data/lib/arel/factory_methods.rb +49 -0
  266. data/lib/arel/insert_manager.rb +49 -0
  267. data/lib/arel/math.rb +45 -0
  268. data/lib/arel/nodes/and.rb +32 -0
  269. data/lib/arel/nodes/ascending.rb +23 -0
  270. data/lib/arel/nodes/binary.rb +126 -0
  271. data/lib/arel/nodes/bind_param.rb +44 -0
  272. data/lib/arel/nodes/case.rb +55 -0
  273. data/lib/arel/nodes/casted.rb +62 -0
  274. data/lib/arel/nodes/comment.rb +29 -0
  275. data/lib/arel/nodes/count.rb +12 -0
  276. data/lib/arel/nodes/delete_statement.rb +45 -0
  277. data/lib/arel/nodes/descending.rb +23 -0
  278. data/lib/arel/nodes/equality.rb +15 -0
  279. data/lib/arel/nodes/extract.rb +24 -0
  280. data/lib/arel/nodes/false.rb +16 -0
  281. data/lib/arel/nodes/full_outer_join.rb +8 -0
  282. data/lib/arel/nodes/function.rb +44 -0
  283. data/lib/arel/nodes/grouping.rb +11 -0
  284. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  285. data/lib/arel/nodes/in.rb +15 -0
  286. data/lib/arel/nodes/infix_operation.rb +92 -0
  287. data/lib/arel/nodes/inner_join.rb +8 -0
  288. data/lib/arel/nodes/insert_statement.rb +37 -0
  289. data/lib/arel/nodes/join_source.rb +20 -0
  290. data/lib/arel/nodes/matches.rb +18 -0
  291. data/lib/arel/nodes/named_function.rb +23 -0
  292. data/lib/arel/nodes/node.rb +51 -0
  293. data/lib/arel/nodes/node_expression.rb +13 -0
  294. data/lib/arel/nodes/ordering.rb +27 -0
  295. data/lib/arel/nodes/outer_join.rb +8 -0
  296. data/lib/arel/nodes/over.rb +15 -0
  297. data/lib/arel/nodes/regexp.rb +16 -0
  298. data/lib/arel/nodes/right_outer_join.rb +8 -0
  299. data/lib/arel/nodes/select_core.rb +67 -0
  300. data/lib/arel/nodes/select_statement.rb +41 -0
  301. data/lib/arel/nodes/sql_literal.rb +19 -0
  302. data/lib/arel/nodes/string_join.rb +11 -0
  303. data/lib/arel/nodes/table_alias.rb +31 -0
  304. data/lib/arel/nodes/terminal.rb +16 -0
  305. data/lib/arel/nodes/true.rb +16 -0
  306. data/lib/arel/nodes/unary.rb +44 -0
  307. data/lib/arel/nodes/unary_operation.rb +20 -0
  308. data/lib/arel/nodes/unqualified_column.rb +22 -0
  309. data/lib/arel/nodes/update_statement.rb +41 -0
  310. data/lib/arel/nodes/values_list.rb +9 -0
  311. data/lib/arel/nodes/window.rb +126 -0
  312. data/lib/arel/nodes/with.rb +11 -0
  313. data/lib/arel/nodes.rb +70 -0
  314. data/lib/arel/order_predications.rb +13 -0
  315. data/lib/arel/predications.rb +250 -0
  316. data/lib/arel/select_manager.rb +270 -0
  317. data/lib/arel/table.rb +118 -0
  318. data/lib/arel/tree_manager.rb +72 -0
  319. data/lib/arel/update_manager.rb +34 -0
  320. data/lib/arel/visitors/dot.rb +308 -0
  321. data/lib/arel/visitors/mysql.rb +93 -0
  322. data/lib/arel/visitors/postgresql.rb +120 -0
  323. data/lib/arel/visitors/sqlite.rb +38 -0
  324. data/lib/arel/visitors/to_sql.rb +899 -0
  325. data/lib/arel/visitors/visitor.rb +45 -0
  326. data/lib/arel/visitors.rb +13 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +54 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  330. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +43 -37
  332. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +26 -0
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +13 -4
  334. data/lib/rails/generators/active_record/migration.rb +35 -1
  335. data/lib/rails/generators/active_record/model/model_generator.rb +55 -22
  336. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  337. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  338. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  339. data/lib/rails/generators/active_record.rb +7 -5
  340. metadata +172 -65
  341. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  342. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  343. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  344. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  345. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  346. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  347. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  348. data/lib/active_record/attribute.rb +0 -163
  349. data/lib/active_record/attribute_decorators.rb +0 -66
  350. data/lib/active_record/attribute_set/builder.rb +0 -106
  351. data/lib/active_record/attribute_set.rb +0 -81
  352. data/lib/active_record/connection_adapters/connection_specification.rb +0 -275
  353. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  354. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  355. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  356. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  357. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  358. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  359. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  360. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  361. data/lib/active_record/type/big_integer.rb +0 -13
  362. data/lib/active_record/type/binary.rb +0 -50
  363. data/lib/active_record/type/boolean.rb +0 -31
  364. data/lib/active_record/type/decimal.rb +0 -64
  365. data/lib/active_record/type/decorator.rb +0 -14
  366. data/lib/active_record/type/float.rb +0 -19
  367. data/lib/active_record/type/integer.rb +0 -59
  368. data/lib/active_record/type/mutable.rb +0 -16
  369. data/lib/active_record/type/numeric.rb +0 -36
  370. data/lib/active_record/type/string.rb +0 -40
  371. data/lib/active_record/type/time_value.rb +0 -38
  372. data/lib/active_record/type/value.rb +0 -110
  373. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
  374. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -1,14 +1,21 @@
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.
6
7
  class ActiveRecordError < StandardError
7
8
  end
8
9
 
10
+ # Raised when trying to use a feature in Active Record which requires Active Job but the gem is not present.
11
+ class ActiveJobRequiredError < ActiveRecordError
12
+ end
13
+
9
14
  # Raised when the single-table inheritance mechanism fails to locate the subclass
10
- # (for example due to improper usage of column that +inheritance_column+ points to).
11
- class SubclassNotFound < ActiveRecordError #:nodoc:
15
+ # (for example due to improper usage of column that
16
+ # {ActiveRecord::Base.inheritance_column}[rdoc-ref:ModelSchema::ClassMethods#inheritance_column]
17
+ # points to).
18
+ class SubclassNotFound < ActiveRecordError
12
19
  end
13
20
 
14
21
  # Raised when an object assigned to an association has an incorrect type.
@@ -35,32 +42,66 @@ module ActiveRecord
35
42
  class AdapterNotSpecified < ActiveRecordError
36
43
  end
37
44
 
45
+ # Raised when a model makes a query but it has not specified an associated table.
46
+ class TableNotSpecified < ActiveRecordError
47
+ end
48
+
38
49
  # Raised when Active Record cannot find database adapter specified in
39
50
  # +config/database.yml+ or programmatically.
40
51
  class AdapterNotFound < ActiveRecordError
41
52
  end
42
53
 
43
- # Raised when connection to the database could not been established (for
44
- # example when +connection=+ is given a nil object).
54
+ # Raised when connection to the database could not been established (for example when
55
+ # {ActiveRecord::Base.connection=}[rdoc-ref:ConnectionHandling#connection]
56
+ # is given a +nil+ object).
45
57
  class ConnectionNotEstablished < ActiveRecordError
46
58
  end
47
59
 
48
- # Raised when Active Record cannot find record by given id or set of ids.
60
+ # Raised when a connection could not be obtained within the connection
61
+ # acquisition timeout period: because max connections in pool
62
+ # are in use.
63
+ class ConnectionTimeoutError < ConnectionNotEstablished
64
+ end
65
+
66
+ # Raised when a pool was unable to get ahold of all its connections
67
+ # to perform a "group" action such as
68
+ # {ActiveRecord::Base.connection_pool.disconnect!}[rdoc-ref:ConnectionAdapters::ConnectionPool#disconnect!]
69
+ # or {ActiveRecord::Base.clear_reloadable_connections!}[rdoc-ref:ConnectionAdapters::ConnectionHandler#clear_reloadable_connections!].
70
+ class ExclusiveConnectionTimeoutError < ConnectionTimeoutError
71
+ end
72
+
73
+ # Raised when a write to the database is attempted on a read only connection.
74
+ class ReadOnlyError < ActiveRecordError
75
+ end
76
+
77
+ # Raised when Active Record cannot find a record by given id or set of ids.
49
78
  class RecordNotFound < ActiveRecordError
79
+ attr_reader :model, :primary_key, :id
80
+
81
+ def initialize(message = nil, model = nil, primary_key = nil, id = nil)
82
+ @primary_key = primary_key
83
+ @model = model
84
+ @id = id
85
+
86
+ super(message)
87
+ end
50
88
  end
51
89
 
52
- # Raised by ActiveRecord::Base.save! and ActiveRecord::Base.create! methods when record cannot be
53
- # saved because record is invalid.
90
+ # Raised by {ActiveRecord::Base#save!}[rdoc-ref:Persistence#save!] and
91
+ # {ActiveRecord::Base.create!}[rdoc-ref:Persistence::ClassMethods#create!]
92
+ # methods when a record is invalid and cannot be saved.
54
93
  class RecordNotSaved < ActiveRecordError
55
94
  attr_reader :record
56
95
 
57
- def initialize(message, record = nil)
96
+ def initialize(message = nil, record = nil)
58
97
  @record = record
59
98
  super(message)
60
99
  end
61
100
  end
62
101
 
63
- # Raised by ActiveRecord::Base.destroy! when a call to destroy would return false.
102
+ # Raised by {ActiveRecord::Base#destroy!}[rdoc-ref:Persistence#destroy!]
103
+ # when a call to {#destroy}[rdoc-ref:Persistence#destroy!]
104
+ # would return false.
64
105
  #
65
106
  # begin
66
107
  # complex_operation_that_internally_calls_destroy!
@@ -71,7 +112,7 @@ module ActiveRecord
71
112
  class RecordNotDestroyed < ActiveRecordError
72
113
  attr_reader :record
73
114
 
74
- def initialize(message, record = nil)
115
+ def initialize(message = nil, record = nil)
75
116
  @record = record
76
117
  super(message)
77
118
  end
@@ -79,32 +120,79 @@ module ActiveRecord
79
120
 
80
121
  # Superclass for all database execution errors.
81
122
  #
82
- # Wraps the underlying database error as +original_exception+.
123
+ # Wraps the underlying database error as +cause+.
83
124
  class StatementInvalid < ActiveRecordError
84
- attr_reader :original_exception
85
-
86
- def initialize(message, original_exception = nil)
87
- super(message)
88
- @original_exception = original_exception
125
+ def initialize(message = nil, sql: nil, binds: nil)
126
+ super(message || $!&.message)
127
+ @sql = sql
128
+ @binds = binds
89
129
  end
130
+
131
+ attr_reader :sql, :binds
90
132
  end
91
133
 
92
134
  # Defunct wrapper class kept for compatibility.
93
- # +StatementInvalid+ wraps the original exception now.
135
+ # StatementInvalid wraps the original exception now.
94
136
  class WrappedDatabaseException < StatementInvalid
95
137
  end
96
138
 
97
- # Raised when a record cannot be inserted because it would violate a uniqueness constraint.
139
+ # Raised when a record cannot be inserted or updated because it would violate a uniqueness constraint.
98
140
  class RecordNotUnique < WrappedDatabaseException
99
141
  end
100
142
 
101
- # Raised when a record cannot be inserted or updated because it references a non-existent record.
143
+ # Raised when a record cannot be inserted or updated because it references a non-existent record,
144
+ # or when a record cannot be deleted because a parent record references it.
102
145
  class InvalidForeignKey < WrappedDatabaseException
103
146
  end
104
147
 
105
- # Raised when number of bind variables in statement given to +:condition+ key
106
- # (for example, when using +find+ method) does not match number of expected
107
- # values supplied.
148
+ # Raised when a foreign key constraint cannot be added because the column type does not match the referenced column type.
149
+ class MismatchedForeignKey < StatementInvalid
150
+ def initialize(
151
+ message: nil,
152
+ sql: nil,
153
+ binds: nil,
154
+ table: nil,
155
+ foreign_key: nil,
156
+ target_table: nil,
157
+ primary_key: nil,
158
+ primary_key_column: nil
159
+ )
160
+ if table
161
+ type = primary_key_column.bigint? ? :bigint : primary_key_column.type
162
+ msg = <<~EOM.squish
163
+ Column `#{foreign_key}` on table `#{table}` does not match column `#{primary_key}` on `#{target_table}`,
164
+ which has type `#{primary_key_column.sql_type}`.
165
+ To resolve this issue, change the type of the `#{foreign_key}` column on `#{table}` to be :#{type}.
166
+ (For example `t.#{type} :#{foreign_key}`).
167
+ EOM
168
+ else
169
+ msg = <<~EOM.squish
170
+ There is a mismatch between the foreign key and primary key column types.
171
+ Verify that the foreign key column type and the primary key of the associated table match types.
172
+ EOM
173
+ end
174
+ if message
175
+ msg << "\nOriginal message: #{message}"
176
+ end
177
+ super(msg, sql: sql, binds: binds)
178
+ end
179
+ end
180
+
181
+ # Raised when a record cannot be inserted or updated because it would violate a not null constraint.
182
+ class NotNullViolation < StatementInvalid
183
+ end
184
+
185
+ # Raised when a record cannot be inserted or updated because a value too long for a column type.
186
+ class ValueTooLong < StatementInvalid
187
+ end
188
+
189
+ # Raised when values that executed are out of range.
190
+ class RangeError < StatementInvalid
191
+ end
192
+
193
+ # Raised when the number of placeholders in an SQL fragment passed to
194
+ # {ActiveRecord::Base.where}[rdoc-ref:QueryMethods#where]
195
+ # does not match the number of values supplied.
108
196
  #
109
197
  # For example, when there are two placeholders with only one value supplied:
110
198
  #
@@ -116,6 +204,15 @@ module ActiveRecord
116
204
  class NoDatabaseError < StatementInvalid
117
205
  end
118
206
 
207
+ # Raised when creating a database if it exists.
208
+ class DatabaseAlreadyExists < StatementInvalid
209
+ end
210
+
211
+ # Raised when PostgreSQL returns 'cached plan must not change result type' and
212
+ # we cannot retry gracefully (e.g. inside a transaction)
213
+ class PreparedStatementCacheExpired < StatementInvalid
214
+ end
215
+
119
216
  # Raised on attempt to save stale record. Record is stale when it's being saved in another query after
120
217
  # instantiation, for example, when two users edit the same wiki page and one starts editing and saves
121
218
  # the page before the other.
@@ -125,16 +222,21 @@ module ActiveRecord
125
222
  class StaleObjectError < ActiveRecordError
126
223
  attr_reader :record, :attempted_action
127
224
 
128
- def initialize(record, attempted_action)
129
- super("Attempted to #{attempted_action} a stale object: #{record.class.name}")
130
- @record = record
131
- @attempted_action = attempted_action
225
+ def initialize(record = nil, attempted_action = nil)
226
+ if record && attempted_action
227
+ @record = record
228
+ @attempted_action = attempted_action
229
+ super("Attempted to #{attempted_action} a stale object: #{record.class.name}.")
230
+ else
231
+ super("Stale object error.")
232
+ end
132
233
  end
133
-
134
234
  end
135
235
 
136
236
  # Raised when association is being configured improperly or user tries to use
137
- # offset and limit together with +has_many+ or +has_and_belongs_to_many+
237
+ # offset and limit together with
238
+ # {ActiveRecord::Base.has_many}[rdoc-ref:Associations::ClassMethods#has_many] or
239
+ # {ActiveRecord::Base.has_and_belongs_to_many}[rdoc-ref:Associations::ClassMethods#has_and_belongs_to_many]
138
240
  # associations.
139
241
  class ConfigurationError < ActiveRecordError
140
242
  end
@@ -143,9 +245,14 @@ module ActiveRecord
143
245
  class ReadOnlyRecord < ActiveRecordError
144
246
  end
145
247
 
146
- # ActiveRecord::Transactions::ClassMethods.transaction uses this exception
147
- # to distinguish a deliberate rollback from other exceptional situations.
148
- # Normally, raising an exception will cause the +transaction+ method to rollback
248
+ # Raised on attempt to lazily load records that are marked as strict loading.
249
+ class StrictLoadingViolationError < ActiveRecordError
250
+ end
251
+
252
+ # {ActiveRecord::Base.transaction}[rdoc-ref:Transactions::ClassMethods#transaction]
253
+ # uses this exception to distinguish a deliberate rollback from other exceptional situations.
254
+ # Normally, raising an exception will cause the
255
+ # {.transaction}[rdoc-ref:Transactions::ClassMethods#transaction] method to rollback
149
256
  # the database transaction *and* pass on the exception. But if you raise an
150
257
  # ActiveRecord::Rollback exception, then the database transaction will be rolled back,
151
258
  # without passing on the exception.
@@ -179,38 +286,29 @@ module ActiveRecord
179
286
  end
180
287
 
181
288
  # Raised when unknown attributes are supplied via mass assignment.
182
- class UnknownAttributeError < NoMethodError
183
-
184
- attr_reader :record, :attribute
185
-
186
- def initialize(record, attribute)
187
- @record = record
188
- @attribute = attribute.to_s
189
- super("unknown attribute '#{attribute}' for #{@record.class}.")
190
- end
191
-
192
- end
289
+ UnknownAttributeError = ActiveModel::UnknownAttributeError
193
290
 
194
291
  # Raised when an error occurred while doing a mass assignment to an attribute through the
195
- # +attributes=+ method. The exception has an +attribute+ property that is the name of the
196
- # offending attribute.
292
+ # {ActiveRecord::Base#attributes=}[rdoc-ref:AttributeAssignment#attributes=] method.
293
+ # The exception has an +attribute+ property that is the name of the offending attribute.
197
294
  class AttributeAssignmentError < ActiveRecordError
198
295
  attr_reader :exception, :attribute
199
296
 
200
- def initialize(message, exception, attribute)
297
+ def initialize(message = nil, exception = nil, attribute = nil)
201
298
  super(message)
202
299
  @exception = exception
203
300
  @attribute = attribute
204
301
  end
205
302
  end
206
303
 
207
- # Raised when there are multiple errors while doing a mass assignment through the +attributes+
304
+ # Raised when there are multiple errors while doing a mass assignment through the
305
+ # {ActiveRecord::Base#attributes=}[rdoc-ref:AttributeAssignment#attributes=]
208
306
  # method. The exception has an +errors+ property that contains an array of AttributeAssignmentError
209
307
  # objects, each corresponding to the error while assigning to an attribute.
210
308
  class MultiparameterAssignmentErrors < ActiveRecordError
211
309
  attr_reader :errors
212
310
 
213
- def initialize(errors)
311
+ def initialize(errors = nil)
214
312
  @errors = errors
215
313
  end
216
314
  end
@@ -219,11 +317,15 @@ module ActiveRecord
219
317
  class UnknownPrimaryKey < ActiveRecordError
220
318
  attr_reader :model
221
319
 
222
- def initialize(model, description = nil)
223
- message = "Unknown primary key for table #{model.table_name} in model #{model}."
224
- message += "\n#{description}" if description
225
- super(message)
226
- @model = model
320
+ def initialize(model = nil, description = nil)
321
+ if model
322
+ message = "Unknown primary key for table #{model.table_name} in model #{model}."
323
+ message += "\n#{description}" if description
324
+ @model = model
325
+ super(message)
326
+ else
327
+ super("Unknown primary key.")
328
+ end
227
329
  end
228
330
  end
229
331
 
@@ -247,7 +349,75 @@ module ActiveRecord
247
349
  # * You are joining an existing open transaction
248
350
  # * You are creating a nested (savepoint) transaction
249
351
  #
250
- # The mysql, mysql2 and postgresql adapters support setting the transaction isolation level.
352
+ # The mysql2 and postgresql adapters support setting the transaction isolation level.
251
353
  class TransactionIsolationError < ActiveRecordError
252
354
  end
355
+
356
+ # TransactionRollbackError will be raised when a transaction is rolled
357
+ # back by the database due to a serialization failure or a deadlock.
358
+ #
359
+ # See the following:
360
+ #
361
+ # * https://www.postgresql.org/docs/current/static/transaction-iso.html
362
+ # * https://dev.mysql.com/doc/mysql-errors/en/server-error-reference.html#error_er_lock_deadlock
363
+ class TransactionRollbackError < StatementInvalid
364
+ end
365
+
366
+ # SerializationFailure will be raised when a transaction is rolled
367
+ # back by the database due to a serialization failure.
368
+ class SerializationFailure < TransactionRollbackError
369
+ end
370
+
371
+ # Deadlocked will be raised when a transaction is rolled
372
+ # back by the database when a deadlock is encountered.
373
+ class Deadlocked < TransactionRollbackError
374
+ end
375
+
376
+ # IrreversibleOrderError is raised when a relation's order is too complex for
377
+ # +reverse_order+ to automatically reverse.
378
+ class IrreversibleOrderError < ActiveRecordError
379
+ end
380
+
381
+ # Superclass for errors that have been aborted (either by client or server).
382
+ class QueryAborted < StatementInvalid
383
+ end
384
+
385
+ # LockWaitTimeout will be raised when lock wait timeout exceeded.
386
+ class LockWaitTimeout < StatementInvalid
387
+ end
388
+
389
+ # StatementTimeout will be raised when statement timeout exceeded.
390
+ class StatementTimeout < QueryAborted
391
+ end
392
+
393
+ # QueryCanceled will be raised when canceling statement due to user request.
394
+ class QueryCanceled < QueryAborted
395
+ end
396
+
397
+ # AdapterTimeout will be raised when database clients times out while waiting from the server.
398
+ class AdapterTimeout < QueryAborted
399
+ end
400
+
401
+ # UnknownAttributeReference is raised when an unknown and potentially unsafe
402
+ # value is passed to a query method. For example, passing a non column name
403
+ # value to a relation's #order method might cause this exception.
404
+ #
405
+ # When working around this exception, caution should be taken to avoid SQL
406
+ # injection vulnerabilities when passing user-provided values to query
407
+ # methods. Known-safe values can be passed to query methods by wrapping them
408
+ # in Arel.sql.
409
+ #
410
+ # For example, the following code would raise this exception:
411
+ #
412
+ # Post.order("length(title)").first
413
+ #
414
+ # The desired result can be accomplished by wrapping the known-safe string
415
+ # in Arel.sql:
416
+ #
417
+ # Post.order(Arel.sql("length(title)")).first
418
+ #
419
+ # Again, such a workaround should *not* be used when passing user-provided
420
+ # values, such as request parameters or model attributes to query methods.
421
+ class UnknownAttributeReference < ActiveRecordError
422
+ end
253
423
  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
@@ -16,15 +17,14 @@ module ActiveRecord
16
17
  # Makes the adapter execute EXPLAIN for the tuples of queries and bindings.
17
18
  # Returns a formatted string ready to be logged.
18
19
  def exec_explain(queries) # :nodoc:
19
- str = queries.map do |sql, bind|
20
- [].tap do |msg|
21
- msg << "EXPLAIN for: #{sql}"
22
- unless bind.empty?
23
- bind_msg = bind.map {|col, val| [col.name, val]}.inspect
24
- msg.last << " #{bind_msg}"
25
- end
26
- msg << connection.explain(sql, bind)
27
- end.join("\n")
20
+ str = queries.map do |sql, binds|
21
+ msg = +"EXPLAIN for: #{sql}"
22
+ unless binds.empty?
23
+ msg << " "
24
+ msg << binds.map { |attr| render_bind(attr) }.inspect
25
+ end
26
+ msg << "\n"
27
+ msg << connection.explain(sql, binds)
28
28
  end.join("\n")
29
29
 
30
30
  # Overriding inspect to be more human readable, especially in the console.
@@ -34,5 +34,21 @@ module ActiveRecord
34
34
 
35
35
  str
36
36
  end
37
+
38
+ private
39
+ def render_bind(attr)
40
+ if ActiveModel::Attribute === attr
41
+ value = if attr.type.binary? && attr.value
42
+ "<#{attr.value_for_database.to_s.bytesize} bytes of binary data>"
43
+ else
44
+ connection.type_cast(attr.value_for_database)
45
+ end
46
+ else
47
+ value = connection.type_cast(attr)
48
+ attr = nil
49
+ end
50
+
51
+ [attr&.name, value]
52
+ end
37
53
  end
38
54
  end
@@ -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
@@ -7,7 +9,7 @@ module ActiveRecord
7
9
  #
8
10
  # returns the collected queries local to the current thread.
9
11
  #
10
- # See the documentation of <tt>ActiveSupport::PerThreadRegistry</tt>
12
+ # See the documentation of ActiveSupport::PerThreadRegistry
11
13
  # for further details.
12
14
  class ExplainRegistry # :nodoc:
13
15
  extend ActiveSupport::PerThreadRegistry
@@ -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:
@@ -14,14 +16,17 @@ module ActiveRecord
14
16
  end
15
17
 
16
18
  # SCHEMA queries cannot be EXPLAINed, also we do not want to run EXPLAIN on
17
- # our own EXPLAINs now matter how loopingly beautiful that would be.
19
+ # our own EXPLAINs no matter how loopingly beautiful that would be.
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].match?(EXPLAINED_SQLS)
25
30
  end
26
31
 
27
32
  ActiveSupport::Notifications.subscribe("sql.active_record", new)
@@ -1,5 +1,6 @@
1
- require 'erb'
2
- require 'yaml'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/configuration_file"
3
4
 
4
5
  module ActiveRecord
5
6
  class FixtureSet
@@ -17,38 +18,56 @@ module ActiveRecord
17
18
 
18
19
  def initialize(file)
19
20
  @file = file
20
- @rows = nil
21
21
  end
22
22
 
23
23
  def each(&block)
24
24
  rows.each(&block)
25
25
  end
26
26
 
27
+ def model_class
28
+ config_row["model_class"]
29
+ end
30
+
31
+ def ignored_fixtures
32
+ config_row["ignore"]
33
+ end
27
34
 
28
35
  private
29
36
  def rows
30
- return @rows if @rows
37
+ @rows ||= raw_rows.reject { |fixture_name, _| fixture_name == "_fixture" }
38
+ end
31
39
 
32
- begin
33
- data = YAML.load(render(IO.read(@file)))
34
- rescue ArgumentError, Psych::SyntaxError => error
35
- raise Fixture::FormatError, "a YAML error occurred parsing #{@file}. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Please have a look at http://www.yaml.org/faq.html\nThe exact error was:\n #{error.class}: #{error}", error.backtrace
40
+ def config_row
41
+ @config_row ||= begin
42
+ row = raw_rows.find { |fixture_name, _| fixture_name == "_fixture" }
43
+ if row
44
+ row.last
45
+ else
46
+ { 'model_class': nil, 'ignore': nil }
47
+ end
36
48
  end
37
- @rows = data ? validate(data).to_a : []
38
49
  end
39
50
 
40
- def render(content)
41
- context = ActiveRecord::FixtureSet::RenderContext.create_subclass.new
42
- ERB.new(content).result(context.get_binding)
51
+ def raw_rows
52
+ @raw_rows ||= begin
53
+ data = ActiveSupport::ConfigurationFile.parse(@file, context:
54
+ ActiveRecord::FixtureSet::RenderContext.create_subclass.new.get_binding)
55
+ data ? validate(data).to_a : []
56
+ rescue RuntimeError => error
57
+ raise Fixture::FormatError, error.message
58
+ end
43
59
  end
44
60
 
45
61
  # Validate our unmarshalled data.
46
62
  def validate(data)
47
63
  unless Hash === data || YAML::Omap === data
48
- raise Fixture::FormatError, 'fixture is not a hash'
64
+ raise Fixture::FormatError, "fixture is not a hash: #{@file}"
49
65
  end
50
66
 
51
- raise Fixture::FormatError unless data.all? { |name, row| Hash === row }
67
+ invalid = data.reject { |_, row| Hash === row }
68
+ if invalid.any?
69
+ raise Fixture::FormatError, "fixture key is not a hash: #{@file}, keys: #{invalid.keys.inspect}"
70
+ end
52
71
  data
53
72
  end
54
73
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class FixtureSet
5
+ class ModelMetadata # :nodoc:
6
+ def initialize(model_class)
7
+ @model_class = model_class
8
+ end
9
+
10
+ def primary_key_name
11
+ @primary_key_name ||= @model_class && @model_class.primary_key
12
+ end
13
+
14
+ def primary_key_type
15
+ @primary_key_type ||= @model_class && @model_class.type_for_attribute(@model_class.primary_key).type
16
+ end
17
+
18
+ def has_primary_key_column?
19
+ @has_primary_key_column ||= primary_key_name &&
20
+ @model_class.columns.any? { |col| col.name == primary_key_name }
21
+ end
22
+
23
+ def timestamp_column_names
24
+ @model_class.all_timestamp_attributes_in_model
25
+ end
26
+
27
+ def inheritance_column_name
28
+ @inheritance_column_name ||= @model_class && @model_class.inheritance_column
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ # NOTE: This class has to be defined in compact style in
4
+ # order for rendering context subclassing to work correctly.
5
+ class ActiveRecord::FixtureSet::RenderContext # :nodoc:
6
+ def self.create_subclass
7
+ Class.new(ActiveRecord::FixtureSet.context_class) do
8
+ def get_binding
9
+ binding()
10
+ end
11
+
12
+ def binary(path)
13
+ %(!!binary "#{Base64.strict_encode64(File.binread(path))}")
14
+ end
15
+ end
16
+ end
17
+ end