activerecord 4.2.0 → 6.1.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (374) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1221 -796
  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 +267 -249
  8. data/lib/active_record/association_relation.rb +45 -7
  9. data/lib/active_record/associations/alias_tracker.rb +40 -43
  10. data/lib/active_record/associations/association.rb +172 -67
  11. data/lib/active_record/associations/association_scope.rb +105 -129
  12. data/lib/active_record/associations/belongs_to_association.rb +85 -59
  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 -33
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +57 -70
  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 +168 -279
  22. data/lib/active_record/associations/collection_proxy.rb +263 -155
  23. data/lib/active_record/associations/foreign_association.rb +33 -0
  24. data/lib/active_record/associations/has_many_association.rb +57 -84
  25. data/lib/active_record/associations/has_many_through_association.rb +70 -82
  26. data/lib/active_record/associations/has_one_association.rb +74 -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 -73
  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 +175 -164
  32. data/lib/active_record/associations/preloader/association.rb +107 -112
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +99 -96
  35. data/lib/active_record/associations/singular_association.rb +18 -45
  36. data/lib/active_record/associations/through_association.rb +49 -24
  37. data/lib/active_record/associations.rb +1845 -1597
  38. data/lib/active_record/attribute_assignment.rb +59 -185
  39. data/lib/active_record/attribute_methods/before_type_cast.rb +20 -7
  40. data/lib/active_record/attribute_methods/dirty.rb +168 -138
  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 +59 -36
  46. data/lib/active_record/attribute_methods/write.rb +25 -56
  47. data/lib/active_record/attribute_methods.rb +153 -162
  48. data/lib/active_record/attributes.rb +234 -70
  49. data/lib/active_record/autosave_association.rb +157 -69
  50. data/lib/active_record/base.rb +49 -50
  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 +46 -13
  54. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +887 -317
  55. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -41
  56. data/lib/active_record/connection_adapters/abstract/database_statements.rb +301 -113
  57. data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -24
  58. data/lib/active_record/connection_adapters/abstract/quoting.rb +187 -60
  59. data/lib/active_record/connection_adapters/abstract/savepoints.rb +9 -7
  60. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +157 -93
  61. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +485 -253
  62. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  63. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +909 -263
  64. data/lib/active_record/connection_adapters/abstract/transaction.rb +254 -92
  65. data/lib/active_record/connection_adapters/abstract_adapter.rb +492 -221
  66. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +580 -608
  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 +196 -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 +271 -0
  78. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
  79. data/lib/active_record/connection_adapters/mysql2_adapter.rb +81 -199
  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 +78 -161
  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 -57
  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 +5 -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 +17 -13
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +6 -3
  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 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +67 -51
  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 +171 -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 +499 -293
  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 +595 -382
  119. data/lib/active_record/connection_adapters/schema_cache.rb +191 -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 +146 -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 -389
  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 +488 -243
  133. data/lib/active_record/counter_cache.rb +71 -50
  134. data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -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 +273 -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 +212 -94
  143. data/lib/active_record/errors.rb +225 -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 +11 -6
  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 +273 -496
  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 +64 -0
  158. data/lib/active_record/legacy_yaml_adapter.rb +52 -0
  159. data/lib/active_record/locale/en.yml +3 -2
  160. data/lib/active_record/locking/optimistic.rb +103 -95
  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 +298 -0
  168. data/lib/active_record/migration/join_table.rb +8 -7
  169. data/lib/active_record/migration.rb +685 -309
  170. data/lib/active_record/model_schema.rb +420 -113
  171. data/lib/active_record/nested_attributes.rb +265 -216
  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 +574 -135
  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 +175 -54
  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 +533 -216
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +485 -310
  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 +326 -244
  186. data/lib/active_record/relation/delegation.rb +76 -84
  187. data/lib/active_record/relation/finder_methods.rb +318 -256
  188. data/lib/active_record/relation/from_clause.rb +30 -0
  189. data/lib/active_record/relation/merger.rb +99 -84
  190. data/lib/active_record/relation/predicate_builder/array_handler.rb +26 -25
  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 +139 -96
  197. data/lib/active_record/relation/query_attribute.rb +50 -0
  198. data/lib/active_record/relation/query_methods.rb +757 -409
  199. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  200. data/lib/active_record/relation/spawn_methods.rb +23 -21
  201. data/lib/active_record/relation/where_clause.rb +239 -0
  202. data/lib/active_record/relation.rb +554 -342
  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 -26
  209. data/lib/active_record/scoping/default.rb +96 -82
  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 +133 -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 +366 -129
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +68 -100
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +87 -39
  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 +291 -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 +181 -152
  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 -41
  231. data/lib/active_record/type/date_time.rb +4 -38
  232. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  233. data/lib/active_record/type/hash_lookup_type_map.rb +12 -5
  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 +33 -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 +65 -48
  251. data/lib/active_record/validations.rb +39 -35
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/active_record.rb +44 -28
  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 -10
  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.rb +7 -5
  339. metadata +175 -65
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  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 -23
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  347. data/lib/active_record/attribute.rb +0 -149
  348. data/lib/active_record/attribute_decorators.rb +0 -66
  349. data/lib/active_record/attribute_set/builder.rb +0 -86
  350. data/lib/active_record/attribute_set.rb +0 -77
  351. data/lib/active_record/connection_adapters/connection_specification.rb +0 -275
  352. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  353. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  354. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  355. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  356. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  357. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  358. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  359. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  360. data/lib/active_record/type/big_integer.rb +0 -13
  361. data/lib/active_record/type/binary.rb +0 -50
  362. data/lib/active_record/type/boolean.rb +0 -30
  363. data/lib/active_record/type/decimal.rb +0 -40
  364. data/lib/active_record/type/decorator.rb +0 -14
  365. data/lib/active_record/type/float.rb +0 -19
  366. data/lib/active_record/type/integer.rb +0 -55
  367. data/lib/active_record/type/mutable.rb +0 -16
  368. data/lib/active_record/type/numeric.rb +0 -36
  369. data/lib/active_record/type/string.rb +0 -36
  370. data/lib/active_record/type/time_value.rb +0 -38
  371. data/lib/active_record/type/value.rb +0 -101
  372. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
  373. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
  374. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -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,40 +112,87 @@ module ActiveRecord
71
112
  class RecordNotDestroyed < ActiveRecordError
72
113
  attr_reader :record
73
114
 
74
- def initialize(record)
115
+ def initialize(message = nil, record = nil)
75
116
  @record = record
76
- super()
117
+ super(message)
77
118
  end
78
119
  end
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,16 @@ module ActiveRecord
219
317
  class UnknownPrimaryKey < ActiveRecordError
220
318
  attr_reader :model
221
319
 
222
- def initialize(model)
223
- super("Unknown primary key for table #{model.table_name} in model #{model}.")
224
- @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
225
329
  end
226
-
227
330
  end
228
331
 
229
332
  # Raised when a relation cannot be mutated because it's already loaded.
@@ -246,7 +349,75 @@ module ActiveRecord
246
349
  # * You are joining an existing open transaction
247
350
  # * You are creating a nested (savepoint) transaction
248
351
  #
249
- # The mysql, mysql2 and postgresql adapters support setting the transaction isolation level.
352
+ # The mysql2 and postgresql adapters support setting the transaction isolation level.
250
353
  class TransactionIsolationError < ActiveRecordError
251
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
252
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)
22
- EXPLAINED_SQLS = /\A\s*(select|update|delete|insert)\b/i
23
+ IGNORED_PAYLOADS = %w(SCHEMA EXPLAIN)
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