activerecord 4.2.11.1 → 6.0.3.5

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 (373) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +721 -1522
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +14 -13
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/advisory_lock_base.rb +18 -0
  8. data/lib/active_record/aggregations.rb +266 -251
  9. data/lib/active_record/association_relation.rb +20 -13
  10. data/lib/active_record/associations/alias_tracker.rb +29 -36
  11. data/lib/active_record/associations/association.rb +128 -57
  12. data/lib/active_record/associations/association_scope.rb +103 -132
  13. data/lib/active_record/associations/belongs_to_association.rb +65 -60
  14. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  15. data/lib/active_record/associations/builder/association.rb +27 -40
  16. data/lib/active_record/associations/builder/belongs_to.rb +69 -55
  17. data/lib/active_record/associations/builder/collection_association.rb +10 -33
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +50 -66
  19. data/lib/active_record/associations/builder/has_many.rb +8 -4
  20. data/lib/active_record/associations/builder/has_one.rb +46 -5
  21. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  22. data/lib/active_record/associations/collection_association.rb +136 -288
  23. data/lib/active_record/associations/collection_proxy.rb +241 -147
  24. data/lib/active_record/associations/foreign_association.rb +10 -1
  25. data/lib/active_record/associations/has_many_association.rb +34 -98
  26. data/lib/active_record/associations/has_many_through_association.rb +60 -87
  27. data/lib/active_record/associations/has_one_association.rb +61 -49
  28. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  29. data/lib/active_record/associations/join_dependency/join_association.rb +38 -86
  30. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  31. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  32. data/lib/active_record/associations/join_dependency.rb +149 -166
  33. data/lib/active_record/associations/preloader/association.rb +90 -123
  34. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  35. data/lib/active_record/associations/preloader.rb +90 -93
  36. data/lib/active_record/associations/singular_association.rb +18 -39
  37. data/lib/active_record/associations/through_association.rb +38 -18
  38. data/lib/active_record/associations.rb +1737 -1597
  39. data/lib/active_record/attribute_assignment.rb +57 -185
  40. data/lib/active_record/attribute_decorators.rb +39 -17
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -9
  42. data/lib/active_record/attribute_methods/dirty.rb +174 -144
  43. data/lib/active_record/attribute_methods/primary_key.rb +90 -84
  44. data/lib/active_record/attribute_methods/query.rb +6 -5
  45. data/lib/active_record/attribute_methods/read.rb +20 -77
  46. data/lib/active_record/attribute_methods/serialization.rb +40 -21
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +57 -37
  48. data/lib/active_record/attribute_methods/write.rb +32 -55
  49. data/lib/active_record/attribute_methods.rb +120 -135
  50. data/lib/active_record/attributes.rb +213 -82
  51. data/lib/active_record/autosave_association.rb +97 -41
  52. data/lib/active_record/base.rb +57 -45
  53. data/lib/active_record/callbacks.rb +101 -76
  54. data/lib/active_record/coders/json.rb +3 -1
  55. data/lib/active_record/coders/yaml_column.rb +23 -12
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +804 -297
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +240 -115
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +83 -24
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +170 -53
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -47
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +371 -242
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +694 -256
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +190 -83
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +473 -202
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +507 -639
  69. data/lib/active_record/connection_adapters/column.rb +56 -43
  70. data/lib/active_record/connection_adapters/connection_specification.rb +174 -153
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +196 -0
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +71 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +58 -181
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +70 -114
  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 +5 -1
  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 +9 -22
  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/jsonb.rb +3 -11
  97. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  99. data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
  100. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
  101. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +51 -34
  102. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  104. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +9 -5
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  110. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  112. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +462 -296
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +558 -356
  117. data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
  118. data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
  119. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +299 -349
  127. data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
  128. data/lib/active_record/connection_handling.rb +167 -41
  129. data/lib/active_record/core.rb +252 -230
  130. data/lib/active_record/counter_cache.rb +70 -49
  131. data/lib/active_record/database_configurations/database_config.rb +37 -0
  132. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  133. data/lib/active_record/database_configurations/url_config.rb +78 -0
  134. data/lib/active_record/database_configurations.rb +233 -0
  135. data/lib/active_record/define_callbacks.rb +22 -0
  136. data/lib/active_record/dynamic_matchers.rb +87 -106
  137. data/lib/active_record/enum.rb +163 -86
  138. data/lib/active_record/errors.rb +188 -53
  139. data/lib/active_record/explain.rb +22 -11
  140. data/lib/active_record/explain_registry.rb +4 -2
  141. data/lib/active_record/explain_subscriber.rb +10 -5
  142. data/lib/active_record/fixture_set/file.rb +35 -9
  143. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  144. data/lib/active_record/fixture_set/render_context.rb +17 -0
  145. data/lib/active_record/fixture_set/table_row.rb +152 -0
  146. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  147. data/lib/active_record/fixtures.rb +227 -501
  148. data/lib/active_record/gem_version.rb +6 -4
  149. data/lib/active_record/inheritance.rb +158 -115
  150. data/lib/active_record/insert_all.rb +179 -0
  151. data/lib/active_record/integration.rb +123 -29
  152. data/lib/active_record/internal_metadata.rb +53 -0
  153. data/lib/active_record/legacy_yaml_adapter.rb +21 -3
  154. data/lib/active_record/locale/en.yml +3 -2
  155. data/lib/active_record/locking/optimistic.rb +86 -96
  156. data/lib/active_record/locking/pessimistic.rb +18 -6
  157. data/lib/active_record/log_subscriber.rb +76 -33
  158. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  159. data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
  160. data/lib/active_record/middleware/database_selector.rb +74 -0
  161. data/lib/active_record/migration/command_recorder.rb +166 -91
  162. data/lib/active_record/migration/compatibility.rb +244 -0
  163. data/lib/active_record/migration/join_table.rb +8 -7
  164. data/lib/active_record/migration.rb +623 -305
  165. data/lib/active_record/model_schema.rb +313 -112
  166. data/lib/active_record/nested_attributes.rb +263 -223
  167. data/lib/active_record/no_touching.rb +15 -2
  168. data/lib/active_record/null_relation.rb +24 -38
  169. data/lib/active_record/persistence.rb +557 -126
  170. data/lib/active_record/query_cache.rb +19 -23
  171. data/lib/active_record/querying.rb +44 -30
  172. data/lib/active_record/railtie.rb +143 -44
  173. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  174. data/lib/active_record/railties/console_sandbox.rb +2 -0
  175. data/lib/active_record/railties/controller_runtime.rb +34 -33
  176. data/lib/active_record/railties/databases.rake +331 -185
  177. data/lib/active_record/readonly_attributes.rb +5 -4
  178. data/lib/active_record/reflection.rb +430 -281
  179. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  180. data/lib/active_record/relation/batches.rb +206 -55
  181. data/lib/active_record/relation/calculations.rb +268 -254
  182. data/lib/active_record/relation/delegation.rb +75 -84
  183. data/lib/active_record/relation/finder_methods.rb +285 -241
  184. data/lib/active_record/relation/from_clause.rb +30 -0
  185. data/lib/active_record/relation/merger.rb +78 -88
  186. data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -26
  187. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  188. data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
  189. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  190. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  191. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  192. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  193. data/lib/active_record/relation/predicate_builder.rb +110 -119
  194. data/lib/active_record/relation/query_attribute.rb +50 -0
  195. data/lib/active_record/relation/query_methods.rb +603 -397
  196. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  197. data/lib/active_record/relation/spawn_methods.rb +11 -14
  198. data/lib/active_record/relation/where_clause.rb +189 -0
  199. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  200. data/lib/active_record/relation.rb +530 -341
  201. data/lib/active_record/result.rb +79 -43
  202. data/lib/active_record/runtime_registry.rb +6 -4
  203. data/lib/active_record/sanitization.rb +144 -121
  204. data/lib/active_record/schema.rb +21 -24
  205. data/lib/active_record/schema_dumper.rb +112 -93
  206. data/lib/active_record/schema_migration.rb +24 -17
  207. data/lib/active_record/scoping/default.rb +98 -83
  208. data/lib/active_record/scoping/named.rb +86 -33
  209. data/lib/active_record/scoping.rb +45 -27
  210. data/lib/active_record/secure_token.rb +40 -0
  211. data/lib/active_record/serialization.rb +5 -5
  212. data/lib/active_record/statement_cache.rb +73 -36
  213. data/lib/active_record/store.rb +127 -42
  214. data/lib/active_record/suppressor.rb +61 -0
  215. data/lib/active_record/table_metadata.rb +90 -0
  216. data/lib/active_record/tasks/database_tasks.rb +307 -100
  217. data/lib/active_record/tasks/mysql_database_tasks.rb +55 -100
  218. data/lib/active_record/tasks/postgresql_database_tasks.rb +80 -41
  219. data/lib/active_record/tasks/sqlite_database_tasks.rb +37 -16
  220. data/lib/active_record/test_databases.rb +23 -0
  221. data/lib/active_record/test_fixtures.rb +225 -0
  222. data/lib/active_record/timestamp.rb +86 -41
  223. data/lib/active_record/touch_later.rb +65 -0
  224. data/lib/active_record/transactions.rb +223 -157
  225. data/lib/active_record/translation.rb +3 -1
  226. data/lib/active_record/type/adapter_specific_registry.rb +126 -0
  227. data/lib/active_record/type/date.rb +4 -45
  228. data/lib/active_record/type/date_time.rb +4 -49
  229. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  230. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  231. data/lib/active_record/type/internal/timezone.rb +17 -0
  232. data/lib/active_record/type/json.rb +30 -0
  233. data/lib/active_record/type/serialized.rb +23 -15
  234. data/lib/active_record/type/text.rb +2 -2
  235. data/lib/active_record/type/time.rb +11 -16
  236. data/lib/active_record/type/type_map.rb +16 -19
  237. data/lib/active_record/type/unsigned_integer.rb +9 -8
  238. data/lib/active_record/type.rb +77 -23
  239. data/lib/active_record/type_caster/connection.rb +34 -0
  240. data/lib/active_record/type_caster/map.rb +20 -0
  241. data/lib/active_record/type_caster.rb +9 -0
  242. data/lib/active_record/validations/absence.rb +25 -0
  243. data/lib/active_record/validations/associated.rb +12 -4
  244. data/lib/active_record/validations/length.rb +26 -0
  245. data/lib/active_record/validations/presence.rb +14 -13
  246. data/lib/active_record/validations/uniqueness.rb +42 -55
  247. data/lib/active_record/validations.rb +38 -35
  248. data/lib/active_record/version.rb +3 -1
  249. data/lib/active_record.rb +42 -22
  250. data/lib/arel/alias_predication.rb +9 -0
  251. data/lib/arel/attributes/attribute.rb +37 -0
  252. data/lib/arel/attributes.rb +22 -0
  253. data/lib/arel/collectors/bind.rb +24 -0
  254. data/lib/arel/collectors/composite.rb +31 -0
  255. data/lib/arel/collectors/plain_string.rb +20 -0
  256. data/lib/arel/collectors/sql_string.rb +20 -0
  257. data/lib/arel/collectors/substitute_binds.rb +28 -0
  258. data/lib/arel/crud.rb +42 -0
  259. data/lib/arel/delete_manager.rb +18 -0
  260. data/lib/arel/errors.rb +9 -0
  261. data/lib/arel/expressions.rb +29 -0
  262. data/lib/arel/factory_methods.rb +49 -0
  263. data/lib/arel/insert_manager.rb +49 -0
  264. data/lib/arel/math.rb +45 -0
  265. data/lib/arel/nodes/and.rb +32 -0
  266. data/lib/arel/nodes/ascending.rb +23 -0
  267. data/lib/arel/nodes/binary.rb +52 -0
  268. data/lib/arel/nodes/bind_param.rb +36 -0
  269. data/lib/arel/nodes/case.rb +55 -0
  270. data/lib/arel/nodes/casted.rb +50 -0
  271. data/lib/arel/nodes/comment.rb +29 -0
  272. data/lib/arel/nodes/count.rb +12 -0
  273. data/lib/arel/nodes/delete_statement.rb +45 -0
  274. data/lib/arel/nodes/descending.rb +23 -0
  275. data/lib/arel/nodes/equality.rb +18 -0
  276. data/lib/arel/nodes/extract.rb +24 -0
  277. data/lib/arel/nodes/false.rb +16 -0
  278. data/lib/arel/nodes/full_outer_join.rb +8 -0
  279. data/lib/arel/nodes/function.rb +44 -0
  280. data/lib/arel/nodes/grouping.rb +8 -0
  281. data/lib/arel/nodes/in.rb +8 -0
  282. data/lib/arel/nodes/infix_operation.rb +80 -0
  283. data/lib/arel/nodes/inner_join.rb +8 -0
  284. data/lib/arel/nodes/insert_statement.rb +37 -0
  285. data/lib/arel/nodes/join_source.rb +20 -0
  286. data/lib/arel/nodes/matches.rb +18 -0
  287. data/lib/arel/nodes/named_function.rb +23 -0
  288. data/lib/arel/nodes/node.rb +50 -0
  289. data/lib/arel/nodes/node_expression.rb +13 -0
  290. data/lib/arel/nodes/outer_join.rb +8 -0
  291. data/lib/arel/nodes/over.rb +15 -0
  292. data/lib/arel/nodes/regexp.rb +16 -0
  293. data/lib/arel/nodes/right_outer_join.rb +8 -0
  294. data/lib/arel/nodes/select_core.rb +67 -0
  295. data/lib/arel/nodes/select_statement.rb +41 -0
  296. data/lib/arel/nodes/sql_literal.rb +16 -0
  297. data/lib/arel/nodes/string_join.rb +11 -0
  298. data/lib/arel/nodes/table_alias.rb +27 -0
  299. data/lib/arel/nodes/terminal.rb +16 -0
  300. data/lib/arel/nodes/true.rb +16 -0
  301. data/lib/arel/nodes/unary.rb +45 -0
  302. data/lib/arel/nodes/unary_operation.rb +20 -0
  303. data/lib/arel/nodes/unqualified_column.rb +22 -0
  304. data/lib/arel/nodes/update_statement.rb +41 -0
  305. data/lib/arel/nodes/values_list.rb +9 -0
  306. data/lib/arel/nodes/window.rb +126 -0
  307. data/lib/arel/nodes/with.rb +11 -0
  308. data/lib/arel/nodes.rb +68 -0
  309. data/lib/arel/order_predications.rb +13 -0
  310. data/lib/arel/predications.rb +256 -0
  311. data/lib/arel/select_manager.rb +271 -0
  312. data/lib/arel/table.rb +110 -0
  313. data/lib/arel/tree_manager.rb +72 -0
  314. data/lib/arel/update_manager.rb +34 -0
  315. data/lib/arel/visitors/depth_first.rb +203 -0
  316. data/lib/arel/visitors/dot.rb +296 -0
  317. data/lib/arel/visitors/ibm_db.rb +34 -0
  318. data/lib/arel/visitors/informix.rb +62 -0
  319. data/lib/arel/visitors/mssql.rb +156 -0
  320. data/lib/arel/visitors/mysql.rb +83 -0
  321. data/lib/arel/visitors/oracle.rb +158 -0
  322. data/lib/arel/visitors/oracle12.rb +65 -0
  323. data/lib/arel/visitors/postgresql.rb +109 -0
  324. data/lib/arel/visitors/sqlite.rb +38 -0
  325. data/lib/arel/visitors/to_sql.rb +888 -0
  326. data/lib/arel/visitors/visitor.rb +45 -0
  327. data/lib/arel/visitors/where_sql.rb +22 -0
  328. data/lib/arel/visitors.rb +20 -0
  329. data/lib/arel/window_predications.rb +9 -0
  330. data/lib/arel.rb +62 -0
  331. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  332. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  333. data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
  334. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  335. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -2
  336. data/lib/rails/generators/active_record/migration.rb +30 -1
  337. data/lib/rails/generators/active_record/model/model_generator.rb +18 -22
  338. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  339. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  340. data/lib/rails/generators/active_record.rb +7 -5
  341. metadata +168 -59
  342. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  343. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  344. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  345. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  346. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  347. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  348. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  349. data/lib/active_record/attribute.rb +0 -163
  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/mysql_adapter.rb +0 -498
  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 -31
  363. data/lib/active_record/type/decimal.rb +0 -64
  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 -59
  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 -40
  370. data/lib/active_record/type/time_value.rb +0 -38
  371. data/lib/active_record/type/value.rb +0 -110
  372. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
  373. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -1,212 +1,84 @@
1
- require 'active_model/forbidden_attributes_protection'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_model/forbidden_attributes_protection"
2
4
 
3
5
  module ActiveRecord
4
6
  module AttributeAssignment
5
- extend ActiveSupport::Concern
6
- include ActiveModel::ForbiddenAttributesProtection
7
-
8
- # Allows you to set all the attributes by passing in a hash of attributes with
9
- # keys matching the attribute names (which again matches the column names).
10
- #
11
- # If the passed hash responds to <tt>permitted?</tt> method and the return value
12
- # of this method is +false+ an <tt>ActiveModel::ForbiddenAttributesError</tt>
13
- # exception is raised.
14
- #
15
- # cat = Cat.new(name: "Gorby", status: "yawning")
16
- # cat.attributes # => { "name" => "Gorby", "status" => "yawning", "created_at" => nil, "updated_at" => nil}
17
- # cat.assign_attributes(status: "sleeping")
18
- # cat.attributes # => { "name" => "Gorby", "status" => "sleeping", "created_at" => nil, "updated_at" => nil }
19
- #
20
- # New attributes will be persisted in the database when the object is saved.
21
- #
22
- # Aliased to <tt>attributes=</tt>.
23
- def assign_attributes(new_attributes)
24
- if !new_attributes.respond_to?(:stringify_keys)
25
- raise ArgumentError, "When assigning attributes, you must pass a hash as an argument."
26
- end
27
- return if new_attributes.blank?
28
-
29
- attributes = new_attributes.stringify_keys
30
- multi_parameter_attributes = []
31
- nested_parameter_attributes = []
32
-
33
- attributes = sanitize_for_mass_assignment(attributes)
34
-
35
- attributes.each do |k, v|
36
- if k.include?("(")
37
- multi_parameter_attributes << [ k, v ]
38
- elsif v.is_a?(Hash)
39
- nested_parameter_attributes << [ k, v ]
40
- else
41
- _assign_attribute(k, v)
42
- end
43
- end
44
-
45
- assign_nested_parameter_attributes(nested_parameter_attributes) unless nested_parameter_attributes.empty?
46
- assign_multiparameter_attributes(multi_parameter_attributes) unless multi_parameter_attributes.empty?
47
- end
48
-
49
- alias attributes= assign_attributes
7
+ include ActiveModel::AttributeAssignment
50
8
 
51
9
  private
52
-
53
- def _assign_attribute(k, v)
54
- public_send("#{k}=", v)
55
- rescue NoMethodError, NameError
56
- if respond_to?("#{k}=")
57
- raise
58
- else
59
- raise UnknownAttributeError.new(self, k)
60
- end
61
- end
62
-
63
- # Assign any deferred nested attributes after the base attributes have been set.
64
- def assign_nested_parameter_attributes(pairs)
65
- pairs.each { |k, v| _assign_attribute(k, v) }
66
- end
67
-
68
- # Instantiates objects for all attribute classes that needs more than one constructor parameter. This is done
69
- # by calling new on the column type or aggregation type (through composed_of) object with these parameters.
70
- # So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate
71
- # written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the
72
- # parentheses to have the parameters typecasted before they're used in the constructor. Use i for Integer and
73
- # f for Float. If all the values for a given attribute are empty, the attribute will be set to +nil+.
74
- def assign_multiparameter_attributes(pairs)
75
- execute_callstack_for_multiparameter_attributes(
76
- extract_callstack_for_multiparameter_attributes(pairs)
77
- )
78
- end
79
-
80
- def execute_callstack_for_multiparameter_attributes(callstack)
81
- errors = []
82
- callstack.each do |name, values_with_empty_parameters|
83
- begin
84
- send("#{name}=", MultiparameterAttribute.new(self, name, values_with_empty_parameters).read_value)
85
- rescue => ex
86
- errors << AttributeAssignmentError.new("error on assignment #{values_with_empty_parameters.values.inspect} to #{name} (#{ex.message})", ex, name)
10
+ def _assign_attributes(attributes)
11
+ multi_parameter_attributes = {}
12
+ nested_parameter_attributes = {}
13
+
14
+ attributes.each do |k, v|
15
+ if k.include?("(")
16
+ multi_parameter_attributes[k] = attributes.delete(k)
17
+ elsif v.is_a?(Hash)
18
+ nested_parameter_attributes[k] = attributes.delete(k)
19
+ end
87
20
  end
88
- end
89
- unless errors.empty?
90
- error_descriptions = errors.map { |ex| ex.message }.join(",")
91
- raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes [#{error_descriptions}]"
92
- end
93
- end
94
-
95
- def extract_callstack_for_multiparameter_attributes(pairs)
96
- attributes = {}
97
-
98
- pairs.each do |(multiparameter_name, value)|
99
- attribute_name = multiparameter_name.split("(").first
100
- attributes[attribute_name] ||= {}
21
+ super(attributes)
101
22
 
102
- parameter_value = value.empty? ? nil : type_cast_attribute_value(multiparameter_name, value)
103
- attributes[attribute_name][find_parameter_position(multiparameter_name)] ||= parameter_value
23
+ assign_nested_parameter_attributes(nested_parameter_attributes) unless nested_parameter_attributes.empty?
24
+ assign_multiparameter_attributes(multi_parameter_attributes) unless multi_parameter_attributes.empty?
104
25
  end
105
26
 
106
- attributes
107
- end
108
-
109
- def type_cast_attribute_value(multiparameter_name, value)
110
- multiparameter_name =~ /\([0-9]*([if])\)/ ? value.send("to_" + $1) : value
111
- end
112
-
113
- def find_parameter_position(multiparameter_name)
114
- multiparameter_name.scan(/\(([0-9]*).*\)/).first.first.to_i
115
- end
116
-
117
- class MultiparameterAttribute #:nodoc:
118
- attr_reader :object, :name, :values, :cast_type
119
-
120
- def initialize(object, name, values)
121
- @object = object
122
- @name = name
123
- @values = values
27
+ # Assign any deferred nested attributes after the base attributes have been set.
28
+ def assign_nested_parameter_attributes(pairs)
29
+ pairs.each { |k, v| _assign_attribute(k, v) }
124
30
  end
125
31
 
126
- def read_value
127
- return if values.values.compact.empty?
128
-
129
- @cast_type = object.type_for_attribute(name)
130
- klass = cast_type.klass
131
-
132
- if klass == Time
133
- read_time
134
- elsif klass == Date
135
- read_date
136
- else
137
- read_other
138
- end
139
- end
140
-
141
- private
142
-
143
- def instantiate_time_object(set_values)
144
- if object.class.send(:create_time_zone_conversion_attribute?, name, cast_type)
145
- Time.zone.local(*set_values)
146
- else
147
- Time.send(object.class.default_timezone, *set_values)
148
- end
32
+ # Instantiates objects for all attribute classes that needs more than one constructor parameter. This is done
33
+ # by calling new on the column type or aggregation type (through composed_of) object with these parameters.
34
+ # So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate
35
+ # written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the
36
+ # parentheses to have the parameters typecasted before they're used in the constructor. Use i for Integer and
37
+ # f for Float. If all the values for a given attribute are empty, the attribute will be set to +nil+.
38
+ def assign_multiparameter_attributes(pairs)
39
+ execute_callstack_for_multiparameter_attributes(
40
+ extract_callstack_for_multiparameter_attributes(pairs)
41
+ )
149
42
  end
150
43
 
151
- def read_time
152
- # If column is a :time (and not :date or :datetime) there is no need to validate if
153
- # there are year/month/day fields
154
- if cast_type.type == :time
155
- # if the column is a time set the values to their defaults as January 1, 1970, but only if they're nil
156
- { 1 => 1970, 2 => 1, 3 => 1 }.each do |key,value|
157
- values[key] ||= value
44
+ def execute_callstack_for_multiparameter_attributes(callstack)
45
+ errors = []
46
+ callstack.each do |name, values_with_empty_parameters|
47
+ if values_with_empty_parameters.each_value.all?(&:nil?)
48
+ values = nil
49
+ else
50
+ values = values_with_empty_parameters
158
51
  end
159
- else
160
- # else column is a timestamp, so if Date bits were not provided, error
161
- validate_required_parameters!([1,2,3])
162
-
163
- # If Date bits were provided but blank, then return nil
164
- return if blank_date_parameter?
52
+ send("#{name}=", values)
53
+ rescue => ex
54
+ errors << AttributeAssignmentError.new("error on assignment #{values_with_empty_parameters.values.inspect} to #{name} (#{ex.message})", ex, name)
165
55
  end
166
-
167
- max_position = extract_max_param(6)
168
- set_values = values.values_at(*(1..max_position))
169
- # If Time bits are not there, then default to 0
170
- (3..5).each { |i| set_values[i] = set_values[i].presence || 0 }
171
- instantiate_time_object(set_values)
172
- end
173
-
174
- def read_date
175
- return if blank_date_parameter?
176
- set_values = values.values_at(1,2,3)
177
- begin
178
- Date.new(*set_values)
179
- rescue ArgumentError # if Date.new raises an exception on an invalid date
180
- instantiate_time_object(set_values).to_date # we instantiate Time object and convert it back to a date thus using Time's logic in handling invalid dates
56
+ unless errors.empty?
57
+ error_descriptions = errors.map(&:message).join(",")
58
+ raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes [#{error_descriptions}]"
181
59
  end
182
60
  end
183
61
 
184
- def read_other
185
- max_position = extract_max_param
186
- positions = (1..max_position)
187
- validate_required_parameters!(positions)
62
+ def extract_callstack_for_multiparameter_attributes(pairs)
63
+ attributes = {}
188
64
 
189
- values.slice(*positions)
190
- end
65
+ pairs.each do |(multiparameter_name, value)|
66
+ attribute_name = multiparameter_name.split("(").first
67
+ attributes[attribute_name] ||= {}
191
68
 
192
- # Checks whether some blank date parameter exists. Note that this is different
193
- # than the validate_required_parameters! method, since it just checks for blank
194
- # positions instead of missing ones, and does not raise in case one blank position
195
- # exists. The caller is responsible to handle the case of this returning true.
196
- def blank_date_parameter?
197
- (1..3).any? { |position| values[position].blank? }
69
+ parameter_value = value.empty? ? nil : type_cast_attribute_value(multiparameter_name, value)
70
+ attributes[attribute_name][find_parameter_position(multiparameter_name)] ||= parameter_value
71
+ end
72
+
73
+ attributes
198
74
  end
199
75
 
200
- # If some position is not provided, it errors out a missing parameter exception.
201
- def validate_required_parameters!(positions)
202
- if missing_parameter = positions.detect { |position| !values.key?(position) }
203
- raise ArgumentError.new("Missing Parameter - #{name}(#{missing_parameter})")
204
- end
76
+ def type_cast_attribute_value(multiparameter_name, value)
77
+ multiparameter_name =~ /\([0-9]*([if])\)/ ? value.send("to_" + $1) : value
205
78
  end
206
79
 
207
- def extract_max_param(upper_cap = 100)
208
- [values.keys.max, upper_cap].min
80
+ def find_parameter_position(multiparameter_name)
81
+ multiparameter_name.scan(/\(([0-9]*).*\)/).first.first.to_i
209
82
  end
210
- end
211
83
  end
212
84
  end
@@ -1,21 +1,44 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module AttributeDecorators # :nodoc:
3
5
  extend ActiveSupport::Concern
4
6
 
5
7
  included do
6
- class_attribute :attribute_type_decorations, instance_accessor: false # :internal:
7
- self.attribute_type_decorations = TypeDecorator.new
8
+ class_attribute :attribute_type_decorations, instance_accessor: false, default: TypeDecorator.new # :internal:
8
9
  end
9
10
 
10
11
  module ClassMethods # :nodoc:
12
+ # This method is an internal API used to create class macros such as
13
+ # +serialize+, and features like time zone aware attributes.
14
+ #
15
+ # Used to wrap the type of an attribute in a new type.
16
+ # When the schema for a model is loaded, attributes with the same name as
17
+ # +column_name+ will have their type yielded to the given block. The
18
+ # return value of that block will be used instead.
19
+ #
20
+ # Subsequent calls where +column_name+ and +decorator_name+ are the same
21
+ # will override the previous decorator, not decorate twice. This can be
22
+ # used to create idempotent class macros like +serialize+
11
23
  def decorate_attribute_type(column_name, decorator_name, &block)
12
24
  matcher = ->(name, _) { name == column_name.to_s }
13
25
  key = "_#{column_name}_#{decorator_name}"
14
26
  decorate_matching_attribute_types(matcher, key, &block)
15
27
  end
16
28
 
29
+ # This method is an internal API used to create higher level features like
30
+ # time zone aware attributes.
31
+ #
32
+ # When the schema for a model is loaded, +matcher+ will be called for each
33
+ # attribute with its name and type. If the matcher returns a truthy value,
34
+ # the type will then be yielded to the given block, and the return value
35
+ # of that block will replace the type.
36
+ #
37
+ # Subsequent calls to this method with the same value for +decorator_name+
38
+ # will replace the previous decorator, not decorate twice. This can be
39
+ # used to ensure that class macros are idempotent.
17
40
  def decorate_matching_attribute_types(matcher, decorator_name, &block)
18
- clear_caches_calculated_from_columns
41
+ reload_schema_from_cache
19
42
  decorator_name = decorator_name.to_s
20
43
 
21
44
  # Create new hashes so we don't modify parent classes
@@ -23,13 +46,13 @@ module ActiveRecord
23
46
  end
24
47
 
25
48
  private
26
-
27
- def add_user_provided_columns(*)
28
- super.map do |column|
29
- decorated_type = attribute_type_decorations.apply(column.name, column.cast_type)
30
- column.with_type(decorated_type)
49
+ def load_schema!
50
+ super
51
+ attribute_types.each do |name, type|
52
+ decorated_type = attribute_type_decorations.apply(name, type)
53
+ define_attribute(name, decorated_type)
54
+ end
31
55
  end
32
- end
33
56
  end
34
57
 
35
58
  class TypeDecorator # :nodoc:
@@ -51,16 +74,15 @@ module ActiveRecord
51
74
  end
52
75
 
53
76
  private
77
+ def decorators_for(name, type)
78
+ matching(name, type).map(&:last)
79
+ end
54
80
 
55
- def decorators_for(name, type)
56
- matching(name, type).map(&:last)
57
- end
58
-
59
- def matching(name, type)
60
- @decorations.values.select do |(matcher, _)|
61
- matcher.call(name, type)
81
+ def matching(name, type)
82
+ @decorations.values.select do |(matcher, _)|
83
+ matcher.call(name, type)
84
+ end
62
85
  end
63
- end
64
86
  end
65
87
  end
66
88
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module AttributeMethods
3
5
  # = Active Record Attribute Methods Before Type Cast
4
6
  #
5
- # <tt>ActiveRecord::AttributeMethods::BeforeTypeCast</tt> provides a way to
7
+ # ActiveRecord::AttributeMethods::BeforeTypeCast provides a way to
6
8
  # read the value of the attributes before typecasting and deserialization.
7
9
  #
8
10
  # class Task < ActiveRecord::Base
@@ -44,6 +46,7 @@ module ActiveRecord
44
46
  # task.read_attribute_before_type_cast('completed_on') # => "2012-10-21"
45
47
  # task.read_attribute_before_type_cast(:completed_on) # => "2012-10-21"
46
48
  def read_attribute_before_type_cast(attr_name)
49
+ sync_with_transaction_state if @transaction_state&.finalized?
47
50
  @attributes[attr_name.to_s].value_before_type_cast
48
51
  end
49
52
 
@@ -58,19 +61,20 @@ module ActiveRecord
58
61
  # task.attributes_before_type_cast
59
62
  # # => {"id"=>nil, "title"=>nil, "is_done"=>true, "completed_on"=>"2012-10-21", "created_at"=>nil, "updated_at"=>nil}
60
63
  def attributes_before_type_cast
64
+ sync_with_transaction_state if @transaction_state&.finalized?
61
65
  @attributes.values_before_type_cast
62
66
  end
63
67
 
64
68
  private
69
+ # Dispatch target for <tt>*_before_type_cast</tt> attribute methods.
70
+ def attribute_before_type_cast(attribute_name)
71
+ read_attribute_before_type_cast(attribute_name)
72
+ end
65
73
 
66
- # Handle *_before_type_cast for method_missing.
67
- def attribute_before_type_cast(attribute_name)
68
- read_attribute_before_type_cast(attribute_name)
69
- end
70
-
71
- def attribute_came_from_user?(attribute_name)
72
- @attributes[attribute_name].came_from_user?
73
- end
74
+ def attribute_came_from_user?(attribute_name)
75
+ sync_with_transaction_state if @transaction_state&.finalized?
76
+ @attributes[attribute_name].came_from_user?
77
+ end
74
78
  end
75
79
  end
76
80
  end