activerecord 4.2.0 → 6.0.5.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 (373) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +852 -801
  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 +267 -249
  9. data/lib/active_record/association_relation.rb +26 -6
  10. data/lib/active_record/associations/alias_tracker.rb +29 -36
  11. data/lib/active_record/associations/association.rb +137 -55
  12. data/lib/active_record/associations/association_scope.rb +110 -132
  13. data/lib/active_record/associations/belongs_to_association.rb +67 -54
  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 -29
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +58 -70
  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 +150 -275
  23. data/lib/active_record/associations/collection_proxy.rb +253 -152
  24. data/lib/active_record/associations/foreign_association.rb +20 -0
  25. data/lib/active_record/associations/has_many_association.rb +35 -84
  26. data/lib/active_record/associations/has_many_through_association.rb +62 -80
  27. data/lib/active_record/associations/has_one_association.rb +62 -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 +43 -78
  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 +159 -162
  33. data/lib/active_record/associations/preloader/association.rb +102 -113
  34. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  35. data/lib/active_record/associations/preloader.rb +96 -95
  36. data/lib/active_record/associations/singular_association.rb +18 -45
  37. data/lib/active_record/associations/through_association.rb +49 -24
  38. data/lib/active_record/associations.rb +1737 -1596
  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 +14 -5
  42. data/lib/active_record/attribute_methods/dirty.rb +174 -134
  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 +61 -37
  48. data/lib/active_record/attribute_methods/write.rb +33 -56
  49. data/lib/active_record/attribute_methods.rb +124 -143
  50. data/lib/active_record/attributes.rb +213 -74
  51. data/lib/active_record/autosave_association.rb +125 -54
  52. data/lib/active_record/base.rb +60 -49
  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 +36 -13
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +810 -291
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +253 -108
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +83 -24
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +171 -53
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +6 -4
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -47
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +383 -239
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +736 -235
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +190 -87
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +487 -192
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +536 -600
  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 +268 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +59 -196
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +71 -115
  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 +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 +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/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 +70 -34
  102. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +67 -51
  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 +465 -291
  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 +565 -363
  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 -364
  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 +277 -233
  130. data/lib/active_record/counter_cache.rb +71 -50
  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 +172 -89
  138. data/lib/active_record/errors.rb +189 -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 +11 -6
  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 +225 -497
  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 +48 -0
  154. data/lib/active_record/locale/en.yml +3 -2
  155. data/lib/active_record/locking/optimistic.rb +99 -98
  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 +636 -290
  165. data/lib/active_record/model_schema.rb +344 -112
  166. data/lib/active_record/nested_attributes.rb +265 -215
  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 +559 -125
  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 +166 -47
  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 +341 -202
  177. data/lib/active_record/readonly_attributes.rb +5 -4
  178. data/lib/active_record/reflection.rb +461 -302
  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 +270 -249
  182. data/lib/active_record/relation/delegation.rb +76 -84
  183. data/lib/active_record/relation/finder_methods.rb +287 -255
  184. data/lib/active_record/relation/from_clause.rb +30 -0
  185. data/lib/active_record/relation/merger.rb +86 -68
  186. data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -25
  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 +112 -92
  194. data/lib/active_record/relation/query_attribute.rb +50 -0
  195. data/lib/active_record/relation/query_methods.rb +612 -392
  196. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  197. data/lib/active_record/relation/spawn_methods.rb +18 -17
  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 +533 -340
  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 -20
  207. data/lib/active_record/scoping/default.rb +98 -82
  208. data/lib/active_record/scoping/named.rb +91 -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 +309 -99
  217. data/lib/active_record/tasks/mysql_database_tasks.rb +58 -89
  218. data/lib/active_record/tasks/postgresql_database_tasks.rb +81 -31
  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 +243 -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 +222 -146
  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 -41
  228. data/lib/active_record/type/date_time.rb +4 -38
  229. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  230. data/lib/active_record/type/hash_lookup_type_map.rb +12 -5
  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 +29 -15
  234. data/lib/active_record/type/text.rb +2 -2
  235. data/lib/active_record/type/time.rb +21 -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 +43 -46
  247. data/lib/active_record/validations.rb +38 -35
  248. data/lib/active_record/version.rb +3 -1
  249. data/lib/active_record.rb +44 -21
  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 -8
  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.rb +7 -5
  340. metadata +174 -63
  341. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  342. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  343. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  344. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  345. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  346. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  347. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  348. data/lib/active_record/attribute.rb +0 -149
  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/mysql_adapter.rb +0 -491
  352. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  353. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  354. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  355. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  356. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  357. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  358. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  359. data/lib/active_record/type/big_integer.rb +0 -13
  360. data/lib/active_record/type/binary.rb +0 -50
  361. data/lib/active_record/type/boolean.rb +0 -30
  362. data/lib/active_record/type/decimal.rb +0 -40
  363. data/lib/active_record/type/decorator.rb +0 -14
  364. data/lib/active_record/type/float.rb +0 -19
  365. data/lib/active_record/type/integer.rb +0 -55
  366. data/lib/active_record/type/mutable.rb +0 -16
  367. data/lib/active_record/type/numeric.rb +0 -36
  368. data/lib/active_record/type/string.rb +0 -36
  369. data/lib/active_record/type/time_value.rb +0 -38
  370. data/lib/active_record/type/value.rb +0 -101
  371. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
  372. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
  373. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -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
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 Fixnum 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
@@ -28,6 +30,7 @@ module ActiveRecord
28
30
 
29
31
  included do
30
32
  attribute_method_suffix "_before_type_cast"
33
+ attribute_method_suffix "_came_from_user?"
31
34
  end
32
35
 
33
36
  # Returns the value of the attribute identified by +attr_name+ before
@@ -43,6 +46,7 @@ module ActiveRecord
43
46
  # task.read_attribute_before_type_cast('completed_on') # => "2012-10-21"
44
47
  # task.read_attribute_before_type_cast(:completed_on) # => "2012-10-21"
45
48
  def read_attribute_before_type_cast(attr_name)
49
+ sync_with_transaction_state if @transaction_state&.finalized?
46
50
  @attributes[attr_name.to_s].value_before_type_cast
47
51
  end
48
52
 
@@ -57,15 +61,20 @@ module ActiveRecord
57
61
  # task.attributes_before_type_cast
58
62
  # # => {"id"=>nil, "title"=>nil, "is_done"=>true, "completed_on"=>"2012-10-21", "created_at"=>nil, "updated_at"=>nil}
59
63
  def attributes_before_type_cast
64
+ sync_with_transaction_state if @transaction_state&.finalized?
60
65
  @attributes.values_before_type_cast
61
66
  end
62
67
 
63
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
64
73
 
65
- # Handle *_before_type_cast for method_missing.
66
- def attribute_before_type_cast(attribute_name)
67
- read_attribute_before_type_cast(attribute_name)
68
- 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
69
78
  end
70
79
  end
71
80
  end