activerecord 5.0.7.2 → 6.1.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 (363) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +829 -2015
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +11 -9
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record.rb +37 -29
  8. data/lib/active_record/aggregations.rb +249 -247
  9. data/lib/active_record/association_relation.rb +30 -18
  10. data/lib/active_record/associations.rb +1714 -1596
  11. data/lib/active_record/associations/alias_tracker.rb +36 -42
  12. data/lib/active_record/associations/association.rb +143 -68
  13. data/lib/active_record/associations/association_scope.rb +98 -94
  14. data/lib/active_record/associations/belongs_to_association.rb +76 -46
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
  16. data/lib/active_record/associations/builder/association.rb +27 -28
  17. data/lib/active_record/associations/builder/belongs_to.rb +52 -60
  18. data/lib/active_record/associations/builder/collection_association.rb +12 -22
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +40 -62
  20. data/lib/active_record/associations/builder/has_many.rb +10 -2
  21. data/lib/active_record/associations/builder/has_one.rb +35 -2
  22. data/lib/active_record/associations/builder/singular_association.rb +5 -1
  23. data/lib/active_record/associations/collection_association.rb +104 -259
  24. data/lib/active_record/associations/collection_proxy.rb +169 -125
  25. data/lib/active_record/associations/foreign_association.rb +22 -0
  26. data/lib/active_record/associations/has_many_association.rb +46 -31
  27. data/lib/active_record/associations/has_many_through_association.rb +66 -46
  28. data/lib/active_record/associations/has_one_association.rb +71 -52
  29. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  30. data/lib/active_record/associations/join_dependency.rb +169 -180
  31. data/lib/active_record/associations/join_dependency/join_association.rb +53 -79
  32. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  33. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  34. data/lib/active_record/associations/preloader.rb +97 -104
  35. data/lib/active_record/associations/preloader/association.rb +109 -97
  36. data/lib/active_record/associations/preloader/through_association.rb +77 -76
  37. data/lib/active_record/associations/singular_association.rb +12 -45
  38. data/lib/active_record/associations/through_association.rb +27 -15
  39. data/lib/active_record/attribute_assignment.rb +55 -60
  40. data/lib/active_record/attribute_methods.rb +111 -141
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +17 -9
  42. data/lib/active_record/attribute_methods/dirty.rb +172 -112
  43. data/lib/active_record/attribute_methods/primary_key.rb +88 -91
  44. data/lib/active_record/attribute_methods/query.rb +6 -8
  45. data/lib/active_record/attribute_methods/read.rb +18 -50
  46. data/lib/active_record/attribute_methods/serialization.rb +38 -10
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +38 -66
  48. data/lib/active_record/attribute_methods/write.rb +25 -32
  49. data/lib/active_record/attributes.rb +69 -31
  50. data/lib/active_record/autosave_association.rb +102 -66
  51. data/lib/active_record/base.rb +16 -25
  52. data/lib/active_record/callbacks.rb +202 -43
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +11 -12
  55. data/lib/active_record/connection_adapters.rb +50 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +661 -375
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +14 -38
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +269 -105
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +54 -35
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +137 -93
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +155 -113
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +328 -162
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +591 -259
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +229 -91
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +392 -244
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +457 -582
  69. data/lib/active_record/connection_adapters/column.rb +55 -13
  70. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  71. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +135 -49
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -23
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +79 -49
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +66 -56
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +20 -12
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +74 -37
  82. data/lib/active_record/connection_adapters/pool_config.rb +63 -0
  83. data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
  84. data/lib/active_record/connection_adapters/postgresql/column.rb +39 -28
  85. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +70 -101
  86. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  87. data/lib/active_record/connection_adapters/postgresql/oid.rb +26 -21
  88. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -11
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  90. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -6
  93. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -4
  95. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  96. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  97. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -18
  98. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  101. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  104. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +30 -9
  106. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -30
  107. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  108. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  109. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
  110. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  111. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  112. data/lib/active_record/connection_adapters/postgresql/quoting.rb +98 -38
  113. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +21 -27
  114. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
  115. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  116. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +34 -32
  117. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +426 -324
  118. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +32 -23
  119. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -6
  120. data/lib/active_record/connection_adapters/postgresql_adapter.rb +418 -293
  121. data/lib/active_record/connection_adapters/schema_cache.rb +135 -18
  122. data/lib/active_record/connection_adapters/sql_type_metadata.rb +22 -7
  123. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
  124. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  125. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +72 -18
  126. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -6
  127. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  128. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  129. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
  130. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +282 -290
  131. data/lib/active_record/connection_adapters/statement_pool.rb +9 -8
  132. data/lib/active_record/connection_handling.rb +287 -45
  133. data/lib/active_record/core.rb +385 -181
  134. data/lib/active_record/counter_cache.rb +60 -28
  135. data/lib/active_record/database_configurations.rb +272 -0
  136. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  137. data/lib/active_record/database_configurations/database_config.rb +80 -0
  138. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  139. data/lib/active_record/database_configurations/url_config.rb +53 -0
  140. data/lib/active_record/delegated_type.rb +209 -0
  141. data/lib/active_record/destroy_association_async_job.rb +36 -0
  142. data/lib/active_record/dynamic_matchers.rb +87 -87
  143. data/lib/active_record/enum.rb +122 -47
  144. data/lib/active_record/errors.rb +153 -22
  145. data/lib/active_record/explain.rb +13 -8
  146. data/lib/active_record/explain_registry.rb +3 -1
  147. data/lib/active_record/explain_subscriber.rb +9 -4
  148. data/lib/active_record/fixture_set/file.rb +20 -22
  149. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  150. data/lib/active_record/fixture_set/render_context.rb +17 -0
  151. data/lib/active_record/fixture_set/table_row.rb +152 -0
  152. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  153. data/lib/active_record/fixtures.rb +246 -507
  154. data/lib/active_record/gem_version.rb +6 -4
  155. data/lib/active_record/inheritance.rb +168 -95
  156. data/lib/active_record/insert_all.rb +208 -0
  157. data/lib/active_record/integration.rb +114 -25
  158. data/lib/active_record/internal_metadata.rb +30 -24
  159. data/lib/active_record/legacy_yaml_adapter.rb +11 -5
  160. data/lib/active_record/locking/optimistic.rb +81 -85
  161. data/lib/active_record/locking/pessimistic.rb +22 -6
  162. data/lib/active_record/log_subscriber.rb +68 -31
  163. data/lib/active_record/middleware/database_selector.rb +77 -0
  164. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  165. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  166. data/lib/active_record/migration.rb +439 -342
  167. data/lib/active_record/migration/command_recorder.rb +152 -98
  168. data/lib/active_record/migration/compatibility.rb +229 -60
  169. data/lib/active_record/migration/join_table.rb +8 -7
  170. data/lib/active_record/model_schema.rb +230 -122
  171. data/lib/active_record/nested_attributes.rb +213 -203
  172. data/lib/active_record/no_touching.rb +11 -2
  173. data/lib/active_record/null_relation.rb +12 -34
  174. data/lib/active_record/persistence.rb +471 -97
  175. data/lib/active_record/query_cache.rb +23 -12
  176. data/lib/active_record/querying.rb +43 -25
  177. data/lib/active_record/railtie.rb +155 -43
  178. data/lib/active_record/railties/console_sandbox.rb +2 -0
  179. data/lib/active_record/railties/controller_runtime.rb +34 -33
  180. data/lib/active_record/railties/databases.rake +507 -195
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +245 -269
  183. data/lib/active_record/relation.rb +475 -324
  184. data/lib/active_record/relation/batches.rb +125 -72
  185. data/lib/active_record/relation/batches/batch_enumerator.rb +28 -10
  186. data/lib/active_record/relation/calculations.rb +267 -171
  187. data/lib/active_record/relation/delegation.rb +73 -69
  188. data/lib/active_record/relation/finder_methods.rb +238 -248
  189. data/lib/active_record/relation/from_clause.rb +7 -9
  190. data/lib/active_record/relation/merger.rb +95 -77
  191. data/lib/active_record/relation/predicate_builder.rb +109 -110
  192. data/lib/active_record/relation/predicate_builder/array_handler.rb +22 -17
  193. data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
  194. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  195. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +55 -0
  196. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  197. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  198. data/lib/active_record/relation/query_attribute.rb +33 -2
  199. data/lib/active_record/relation/query_methods.rb +654 -374
  200. data/lib/active_record/relation/record_fetch_warning.rb +8 -6
  201. data/lib/active_record/relation/spawn_methods.rb +15 -14
  202. data/lib/active_record/relation/where_clause.rb +171 -109
  203. data/lib/active_record/result.rb +88 -51
  204. data/lib/active_record/runtime_registry.rb +5 -3
  205. data/lib/active_record/sanitization.rb +73 -100
  206. data/lib/active_record/schema.rb +7 -14
  207. data/lib/active_record/schema_dumper.rb +101 -69
  208. data/lib/active_record/schema_migration.rb +16 -12
  209. data/lib/active_record/scoping.rb +20 -20
  210. data/lib/active_record/scoping/default.rb +92 -95
  211. data/lib/active_record/scoping/named.rb +39 -30
  212. data/lib/active_record/secure_token.rb +19 -9
  213. data/lib/active_record/serialization.rb +7 -3
  214. data/lib/active_record/signed_id.rb +116 -0
  215. data/lib/active_record/statement_cache.rb +80 -29
  216. data/lib/active_record/store.rb +122 -42
  217. data/lib/active_record/suppressor.rb +6 -3
  218. data/lib/active_record/table_metadata.rb +51 -39
  219. data/lib/active_record/tasks/database_tasks.rb +332 -115
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +66 -104
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +84 -56
  222. data/lib/active_record/tasks/sqlite_database_tasks.rb +40 -19
  223. data/lib/active_record/test_databases.rb +24 -0
  224. data/lib/active_record/test_fixtures.rb +246 -0
  225. data/lib/active_record/timestamp.rb +70 -38
  226. data/lib/active_record/touch_later.rb +26 -24
  227. data/lib/active_record/transactions.rb +121 -184
  228. data/lib/active_record/translation.rb +3 -1
  229. data/lib/active_record/type.rb +29 -17
  230. data/lib/active_record/type/adapter_specific_registry.rb +44 -48
  231. data/lib/active_record/type/date.rb +2 -0
  232. data/lib/active_record/type/date_time.rb +2 -0
  233. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  234. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  235. data/lib/active_record/type/internal/timezone.rb +2 -0
  236. data/lib/active_record/type/json.rb +30 -0
  237. data/lib/active_record/type/serialized.rb +20 -9
  238. data/lib/active_record/type/text.rb +11 -0
  239. data/lib/active_record/type/time.rb +12 -1
  240. data/lib/active_record/type/type_map.rb +14 -17
  241. data/lib/active_record/type/unsigned_integer.rb +16 -0
  242. data/lib/active_record/type_caster.rb +4 -2
  243. data/lib/active_record/type_caster/connection.rb +17 -13
  244. data/lib/active_record/type_caster/map.rb +10 -6
  245. data/lib/active_record/validations.rb +8 -5
  246. data/lib/active_record/validations/absence.rb +2 -0
  247. data/lib/active_record/validations/associated.rb +4 -3
  248. data/lib/active_record/validations/length.rb +2 -0
  249. data/lib/active_record/validations/numericality.rb +35 -0
  250. data/lib/active_record/validations/presence.rb +4 -2
  251. data/lib/active_record/validations/uniqueness.rb +52 -45
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/arel.rb +54 -0
  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.rb +70 -0
  269. data/lib/arel/nodes/and.rb +32 -0
  270. data/lib/arel/nodes/ascending.rb +23 -0
  271. data/lib/arel/nodes/binary.rb +126 -0
  272. data/lib/arel/nodes/bind_param.rb +44 -0
  273. data/lib/arel/nodes/case.rb +55 -0
  274. data/lib/arel/nodes/casted.rb +62 -0
  275. data/lib/arel/nodes/comment.rb +29 -0
  276. data/lib/arel/nodes/count.rb +12 -0
  277. data/lib/arel/nodes/delete_statement.rb +45 -0
  278. data/lib/arel/nodes/descending.rb +23 -0
  279. data/lib/arel/nodes/equality.rb +15 -0
  280. data/lib/arel/nodes/extract.rb +24 -0
  281. data/lib/arel/nodes/false.rb +16 -0
  282. data/lib/arel/nodes/full_outer_join.rb +8 -0
  283. data/lib/arel/nodes/function.rb +44 -0
  284. data/lib/arel/nodes/grouping.rb +11 -0
  285. data/lib/arel/nodes/homogeneous_in.rb +72 -0
  286. data/lib/arel/nodes/in.rb +15 -0
  287. data/lib/arel/nodes/infix_operation.rb +92 -0
  288. data/lib/arel/nodes/inner_join.rb +8 -0
  289. data/lib/arel/nodes/insert_statement.rb +37 -0
  290. data/lib/arel/nodes/join_source.rb +20 -0
  291. data/lib/arel/nodes/matches.rb +18 -0
  292. data/lib/arel/nodes/named_function.rb +23 -0
  293. data/lib/arel/nodes/node.rb +51 -0
  294. data/lib/arel/nodes/node_expression.rb +13 -0
  295. data/lib/arel/nodes/ordering.rb +27 -0
  296. data/lib/arel/nodes/outer_join.rb +8 -0
  297. data/lib/arel/nodes/over.rb +15 -0
  298. data/lib/arel/nodes/regexp.rb +16 -0
  299. data/lib/arel/nodes/right_outer_join.rb +8 -0
  300. data/lib/arel/nodes/select_core.rb +67 -0
  301. data/lib/arel/nodes/select_statement.rb +41 -0
  302. data/lib/arel/nodes/sql_literal.rb +19 -0
  303. data/lib/arel/nodes/string_join.rb +11 -0
  304. data/lib/arel/nodes/table_alias.rb +31 -0
  305. data/lib/arel/nodes/terminal.rb +16 -0
  306. data/lib/arel/nodes/true.rb +16 -0
  307. data/lib/arel/nodes/unary.rb +44 -0
  308. data/lib/arel/nodes/unary_operation.rb +20 -0
  309. data/lib/arel/nodes/unqualified_column.rb +22 -0
  310. data/lib/arel/nodes/update_statement.rb +41 -0
  311. data/lib/arel/nodes/values_list.rb +9 -0
  312. data/lib/arel/nodes/window.rb +126 -0
  313. data/lib/arel/nodes/with.rb +11 -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.rb +13 -0
  321. data/lib/arel/visitors/dot.rb +308 -0
  322. data/lib/arel/visitors/mysql.rb +93 -0
  323. data/lib/arel/visitors/postgresql.rb +120 -0
  324. data/lib/arel/visitors/sqlite.rb +38 -0
  325. data/lib/arel/visitors/to_sql.rb +899 -0
  326. data/lib/arel/visitors/visitor.rb +45 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/rails/generators/active_record.rb +7 -5
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  330. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  331. data/lib/rails/generators/active_record/migration.rb +22 -3
  332. data/lib/rails/generators/active_record/migration/migration_generator.rb +38 -35
  333. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +3 -1
  334. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +7 -5
  335. data/lib/rails/generators/active_record/model/model_generator.rb +41 -25
  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 → model.rb.tt} +10 -1
  338. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  339. metadata +141 -57
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  342. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  343. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  344. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  347. data/lib/active_record/attribute.rb +0 -213
  348. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  349. data/lib/active_record/attribute_decorators.rb +0 -67
  350. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  351. data/lib/active_record/attribute_set.rb +0 -110
  352. data/lib/active_record/attribute_set/builder.rb +0 -132
  353. data/lib/active_record/collection_cache_key.rb +0 -50
  354. data/lib/active_record/connection_adapters/connection_specification.rb +0 -263
  355. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -22
  356. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  357. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  358. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  359. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -17
  360. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  361. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  362. data/lib/active_record/relation/where_clause_factory.rb +0 -38
  363. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  # = Active Record \RecordInvalid
3
5
  #
@@ -38,15 +40,16 @@ module ActiveRecord
38
40
  include ActiveModel::Validations
39
41
 
40
42
  # The validation process on save can be skipped by passing <tt>validate: false</tt>.
43
+ # The validation context can be changed by passing <tt>context: context</tt>.
41
44
  # The regular {ActiveRecord::Base#save}[rdoc-ref:Persistence#save] method is replaced
42
45
  # with this when the validations module is mixed in, which it is by default.
43
- def save(options={})
46
+ def save(**options)
44
47
  perform_validations(options) ? super : false
45
48
  end
46
49
 
47
50
  # Attempts to save the record just like {ActiveRecord::Base#save}[rdoc-ref:Base#save] but
48
51
  # will raise an ActiveRecord::RecordInvalid exception instead of returning +false+ if the record is not valid.
49
- def save!(options={})
52
+ def save!(**options)
50
53
  perform_validations(options) ? super : raise_validation_error
51
54
  end
52
55
 
@@ -68,8 +71,7 @@ module ActiveRecord
68
71
 
69
72
  alias_method :validate, :valid?
70
73
 
71
- protected
72
-
74
+ private
73
75
  def default_validation_context
74
76
  new_record? ? :create : :update
75
77
  end
@@ -78,7 +80,7 @@ module ActiveRecord
78
80
  raise(RecordInvalid.new(self))
79
81
  end
80
82
 
81
- def perform_validations(options={}) # :nodoc:
83
+ def perform_validations(options = {})
82
84
  options[:validate] == false || valid?(options[:context])
83
85
  end
84
86
  end
@@ -89,3 +91,4 @@ require "active_record/validations/uniqueness"
89
91
  require "active_record/validations/presence"
90
92
  require "active_record/validations/absence"
91
93
  require "active_record/validations/length"
94
+ require "active_record/validations/numericality"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Validations
3
5
  class AbsenceValidator < ActiveModel::Validations::AbsenceValidator # :nodoc:
@@ -1,14 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Validations
3
5
  class AssociatedValidator < ActiveModel::EachValidator #:nodoc:
4
6
  def validate_each(record, attribute, value)
5
7
  if Array(value).reject { |r| valid_object?(r) }.any?
6
- record.errors.add(attribute, :invalid, options.merge(value: value))
8
+ record.errors.add(attribute, :invalid, **options.merge(value: value))
7
9
  end
8
10
  end
9
11
 
10
12
  private
11
-
12
13
  def valid_object?(record)
13
14
  (record.respond_to?(:marked_for_destruction?) && record.marked_for_destruction?) || record.valid?
14
15
  end
@@ -37,7 +38,7 @@ module ActiveRecord
37
38
  #
38
39
  # * <tt>:message</tt> - A custom error message (default is: "is invalid").
39
40
  # * <tt>:on</tt> - Specifies the contexts where this validation is active.
40
- # Runs in all validation contexts by default (nil). You can pass a symbol
41
+ # Runs in all validation contexts by default +nil+. You can pass a symbol
41
42
  # or an array of symbols. (e.g. <tt>on: :create</tt> or
42
43
  # <tt>on: :custom_validation_context</tt> or
43
44
  # <tt>on: [:create, :custom_validation_context]</tt>)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Validations
3
5
  class LengthValidator < ActiveModel::Validations::LengthValidator # :nodoc:
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Validations
5
+ class NumericalityValidator < ActiveModel::Validations::NumericalityValidator # :nodoc:
6
+ def validate_each(record, attribute, value, precision: nil, scale: nil)
7
+ precision = [column_precision_for(record, attribute) || BigDecimal.double_fig, BigDecimal.double_fig].min
8
+ scale = column_scale_for(record, attribute)
9
+ super(record, attribute, value, precision: precision, scale: scale)
10
+ end
11
+
12
+ private
13
+ def column_precision_for(record, attribute)
14
+ record.class.type_for_attribute(attribute.to_s)&.precision
15
+ end
16
+
17
+ def column_scale_for(record, attribute)
18
+ record.class.type_for_attribute(attribute.to_s)&.scale
19
+ end
20
+ end
21
+
22
+ module ClassMethods
23
+ # Validates whether the value of the specified attribute is numeric by
24
+ # trying to convert it to a float with Kernel.Float (if <tt>only_integer</tt>
25
+ # is +false+) or applying it to the regular expression <tt>/\A[\+\-]?\d+\z/</tt>
26
+ # (if <tt>only_integer</tt> is set to +true+). Kernel.Float precision
27
+ # defaults to the column's precision value or 15.
28
+ #
29
+ # See ActiveModel::Validations::HelperMethods.validates_numericality_of for more information.
30
+ def validates_numericality_of(*attr_names)
31
+ validates_with NumericalityValidator, _merge_attributes(attr_names)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Validations
3
5
  class PresenceValidator < ActiveModel::Validations::PresenceValidator # :nodoc:
@@ -44,7 +46,7 @@ module ActiveRecord
44
46
  # Configuration options:
45
47
  # * <tt>:message</tt> - A custom error message (default is: "can't be blank").
46
48
  # * <tt>:on</tt> - Specifies the contexts where this validation is active.
47
- # Runs in all validation contexts by default (nil). You can pass a symbol
49
+ # Runs in all validation contexts by default +nil+. You can pass a symbol
48
50
  # or an array of symbols. (e.g. <tt>on: :create</tt> or
49
51
  # <tt>on: :custom_validation_context</tt> or
50
52
  # <tt>on: [:create, :custom_validation_context]</tt>)
@@ -57,7 +59,7 @@ module ActiveRecord
57
59
  # or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The method,
58
60
  # proc or string should return or evaluate to a +true+ or +false+ value.
59
61
  # * <tt>:strict</tt> - Specifies whether validation should be strict.
60
- # See ActiveModel::Validation#validates! for more information.
62
+ # See ActiveModel::Validations#validates! for more information.
61
63
  def validates_presence_of(*attr_names)
62
64
  validates_with PresenceValidator, _merge_attributes(attr_names)
63
65
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Validations
3
5
  class UniquenessValidator < ActiveModel::EachValidator # :nodoc:
@@ -6,41 +8,53 @@ module ActiveRecord
6
8
  raise ArgumentError, "#{options[:conditions]} was passed as :conditions but is not callable. " \
7
9
  "Pass a callable instead: `conditions: -> { where(approved: true) }`"
8
10
  end
9
- super({ case_sensitive: true }.merge!(options))
11
+ unless Array(options[:scope]).all? { |scope| scope.respond_to?(:to_sym) }
12
+ raise ArgumentError, "#{options[:scope]} is not supported format for :scope option. " \
13
+ "Pass a symbol or an array of symbols instead: `scope: :user_id`"
14
+ end
15
+ super
10
16
  @klass = options[:class]
11
17
  end
12
18
 
13
19
  def validate_each(record, attribute, value)
14
20
  finder_class = find_finder_class_for(record)
15
- table = finder_class.arel_table
16
21
  value = map_enum_attribute(finder_class, attribute, value)
17
22
 
18
- relation = build_relation(finder_class, table, attribute, value)
23
+ relation = build_relation(finder_class, attribute, value)
19
24
  if record.persisted?
20
25
  if finder_class.primary_key
21
- relation = relation.where.not(finder_class.primary_key => record.id_was || record.id)
26
+ relation = relation.where.not(finder_class.primary_key => record.id_in_database)
22
27
  else
23
- raise UnknownPrimaryKey.new(finder_class, "Can not validate uniqueness for persisted record without primary key.")
28
+ raise UnknownPrimaryKey.new(finder_class, "Cannot validate uniqueness for persisted record without primary key.")
29
+ end
30
+ end
31
+ relation = scope_relation(record, relation)
32
+
33
+ if options[:conditions]
34
+ conditions = options[:conditions]
35
+
36
+ relation = if conditions.arity.zero?
37
+ relation.instance_exec(&conditions)
38
+ else
39
+ relation.instance_exec(record, &conditions)
24
40
  end
25
41
  end
26
- relation = scope_relation(record, table, relation)
27
- relation = relation.merge(options[:conditions]) if options[:conditions]
28
42
 
29
43
  if relation.exists?
30
44
  error_options = options.except(:case_sensitive, :scope, :conditions)
31
45
  error_options[:value] = value
32
46
 
33
- record.errors.add(attribute, :taken, error_options)
47
+ record.errors.add(attribute, :taken, **error_options)
34
48
  end
35
49
  end
36
50
 
37
- protected
51
+ private
38
52
  # The check for an existing value should be run from a class that
39
53
  # isn't abstract. This means working down from the current class
40
54
  # (self), to the first non-abstract class. Since classes don't know
41
55
  # their subclasses, we have to build the hierarchy between self and
42
56
  # the record's class.
43
- def find_finder_class_for(record) #:nodoc:
57
+ def find_finder_class_for(record)
44
58
  class_hierarchy = [record.class]
45
59
 
46
60
  while class_hierarchy.first != @klass
@@ -50,46 +64,30 @@ module ActiveRecord
50
64
  class_hierarchy.detect { |klass| !klass.abstract_class? }
51
65
  end
52
66
 
53
- def build_relation(klass, table, attribute, value) #:nodoc:
54
- if reflection = klass._reflect_on_association(attribute)
55
- attribute = reflection.foreign_key
56
- value = value.attributes[reflection.klass.primary_key] unless value.nil?
57
- end
67
+ def build_relation(klass, attribute, value)
68
+ relation = klass.unscoped
69
+ comparison = relation.bind_attribute(attribute, value) do |attr, bind|
70
+ return relation.none! if bind.unboundable?
58
71
 
59
- # the attribute may be an aliased attribute
60
- if klass.attribute_alias?(attribute)
61
- attribute = klass.attribute_alias(attribute)
72
+ if !options.key?(:case_sensitive) || bind.nil?
73
+ klass.connection.default_uniqueness_comparison(attr, bind)
74
+ elsif options[:case_sensitive]
75
+ klass.connection.case_sensitive_comparison(attr, bind)
76
+ else
77
+ # will use SQL LOWER function before comparison, unless it detects a case insensitive collation
78
+ klass.connection.case_insensitive_comparison(attr, bind)
79
+ end
62
80
  end
63
81
 
64
- attribute_name = attribute.to_s
65
-
66
- column = klass.columns_hash[attribute_name]
67
- cast_type = klass.type_for_attribute(attribute_name)
68
- value = cast_type.serialize(value)
69
- value = klass.connection.type_cast(value)
70
-
71
- comparison = if !options[:case_sensitive] && !value.nil?
72
- # will use SQL LOWER function before comparison, unless it detects a case insensitive collation
73
- klass.connection.case_insensitive_comparison(table, attribute, column, value)
74
- else
75
- klass.connection.case_sensitive_comparison(table, attribute, column, value)
76
- end
77
- if value.nil?
78
- klass.unscoped.where(comparison)
79
- else
80
- bind = Relation::QueryAttribute.new(attribute_name, value, Type::Value.new)
81
- klass.unscoped.where(comparison, bind)
82
- end
83
- rescue RangeError
84
- klass.none
82
+ relation.where!(comparison)
85
83
  end
86
84
 
87
- def scope_relation(record, table, relation)
85
+ def scope_relation(record, relation)
88
86
  Array(options[:scope]).each do |scope_item|
89
87
  scope_value = if record.class._reflect_on_association(scope_item)
90
88
  record.association(scope_item).reader
91
89
  else
92
- record._read_attribute(scope_item)
90
+ record.read_attribute(scope_item)
93
91
  end
94
92
  relation = relation.where(scope_item => scope_value)
95
93
  end
@@ -137,6 +135,17 @@ module ActiveRecord
137
135
  # validates_uniqueness_of :title, conditions: -> { where.not(status: 'archived') }
138
136
  # end
139
137
  #
138
+ # To build conditions based on the record's state, define the conditions
139
+ # callable with a parameter, which will be the record itself. This
140
+ # example validates the title is unique for the year of publication:
141
+ #
142
+ # class Article < ActiveRecord::Base
143
+ # validates_uniqueness_of :title, conditions: ->(article) {
144
+ # published_at = article.published_at
145
+ # where(published_at: published_at.beginning_of_year..published_at.end_of_year)
146
+ # }
147
+ # end
148
+ #
140
149
  # When the record is created, a check is performed to make sure that no
141
150
  # record exists in the database with the given value for the specified
142
151
  # attribute (that maps to a column). When the record is updated,
@@ -204,9 +213,7 @@ module ActiveRecord
204
213
  # | # Boom! We now have a duplicate
205
214
  # | # title!
206
215
  #
207
- # This could even happen if you use transactions with the 'serializable'
208
- # isolation level. The best way to work around this problem is to add a unique
209
- # index to the database table using
216
+ # The best way to work around this problem is to add a unique index to the database table using
210
217
  # {connection.add_index}[rdoc-ref:ConnectionAdapters::SchemaStatements#add_index].
211
218
  # In the rare case that a race condition occurs, the database will guarantee
212
219
  # the field's uniqueness.
@@ -218,7 +225,7 @@ module ActiveRecord
218
225
  # can catch it and restart the transaction (e.g. by telling the user
219
226
  # that the title already exists, and asking them to re-enter the title).
220
227
  # This technique is also known as
221
- # {optimistic concurrency control}[http://en.wikipedia.org/wiki/Optimistic_concurrency_control].
228
+ # {optimistic concurrency control}[https://en.wikipedia.org/wiki/Optimistic_concurrency_control].
222
229
  #
223
230
  # The bundled ActiveRecord::ConnectionAdapters distinguish unique index
224
231
  # constraint errors from other types of database errors by throwing an
@@ -1,4 +1,6 @@
1
- require_relative 'gem_version'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "gem_version"
2
4
 
3
5
  module ActiveRecord
4
6
  # Returns the version of the currently loaded ActiveRecord as a <tt>Gem::Version</tt>
data/lib/arel.rb ADDED
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "arel/errors"
4
+
5
+ require "arel/crud"
6
+ require "arel/factory_methods"
7
+
8
+ require "arel/expressions"
9
+ require "arel/predications"
10
+ require "arel/window_predications"
11
+ require "arel/math"
12
+ require "arel/alias_predication"
13
+ require "arel/order_predications"
14
+ require "arel/table"
15
+ require "arel/attributes/attribute"
16
+
17
+ require "arel/visitors"
18
+ require "arel/collectors/sql_string"
19
+
20
+ require "arel/tree_manager"
21
+ require "arel/insert_manager"
22
+ require "arel/select_manager"
23
+ require "arel/update_manager"
24
+ require "arel/delete_manager"
25
+ require "arel/nodes"
26
+
27
+ module Arel
28
+ VERSION = "10.0.0"
29
+
30
+ # Wrap a known-safe SQL string for passing to query methods, e.g.
31
+ #
32
+ # Post.order(Arel.sql("length(title)")).last
33
+ #
34
+ # Great caution should be taken to avoid SQL injection vulnerabilities.
35
+ # This method should not be used with unsafe values such as request
36
+ # parameters or model attributes.
37
+ def self.sql(raw_sql)
38
+ Arel::Nodes::SqlLiteral.new raw_sql
39
+ end
40
+
41
+ def self.star # :nodoc:
42
+ sql "*"
43
+ end
44
+
45
+ def self.arel_node?(value) # :nodoc:
46
+ value.is_a?(Arel::Nodes::Node) || value.is_a?(Arel::Attribute) || value.is_a?(Arel::Nodes::SqlLiteral)
47
+ end
48
+
49
+ def self.fetch_attribute(value, &block) # :nodoc:
50
+ unless String === value
51
+ value.fetch_attribute(&block)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module AliasPredication
5
+ def as(other)
6
+ Nodes::As.new self, Nodes::SqlLiteral.new(other)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Attributes
5
+ class Attribute < Struct.new :relation, :name
6
+ include Arel::Expressions
7
+ include Arel::Predications
8
+ include Arel::AliasPredication
9
+ include Arel::OrderPredications
10
+ include Arel::Math
11
+
12
+ def type_caster
13
+ relation.type_for_attribute(name)
14
+ end
15
+
16
+ ###
17
+ # Create a node for lowering this attribute
18
+ def lower
19
+ relation.lower self
20
+ end
21
+
22
+ def type_cast_for_database(value)
23
+ relation.type_cast_for_database(name, value)
24
+ end
25
+
26
+ def able_to_type_cast?
27
+ relation.able_to_type_cast?
28
+ end
29
+ end
30
+
31
+ class String < Attribute; end
32
+ class Time < Attribute; end
33
+ class Boolean < Attribute; end
34
+ class Decimal < Attribute; end
35
+ class Float < Attribute; end
36
+ class Integer < Attribute; end
37
+ class Undefined < Attribute; end
38
+ end
39
+
40
+ Attribute = Attributes::Attribute
41
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Collectors
5
+ class Bind
6
+ def initialize
7
+ @binds = []
8
+ end
9
+
10
+ def <<(str)
11
+ self
12
+ end
13
+
14
+ def add_bind(bind)
15
+ @binds << bind
16
+ self
17
+ end
18
+
19
+ def add_binds(binds)
20
+ @binds.concat binds
21
+ self
22
+ end
23
+
24
+ def value
25
+ @binds
26
+ end
27
+ end
28
+ end
29
+ end