activerecord 3.2.6 → 6.0.0

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 (371) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +611 -6417
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +44 -47
  5. data/examples/performance.rb +79 -71
  6. data/examples/simple.rb +6 -5
  7. data/lib/active_record/aggregations.rb +268 -238
  8. data/lib/active_record/association_relation.rb +40 -0
  9. data/lib/active_record/associations/alias_tracker.rb +47 -42
  10. data/lib/active_record/associations/association.rb +173 -81
  11. data/lib/active_record/associations/association_scope.rb +124 -92
  12. data/lib/active_record/associations/belongs_to_association.rb +83 -38
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +11 -9
  14. data/lib/active_record/associations/builder/association.rb +113 -32
  15. data/lib/active_record/associations/builder/belongs_to.rb +105 -60
  16. data/lib/active_record/associations/builder/collection_association.rb +53 -56
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +98 -41
  18. data/lib/active_record/associations/builder/has_many.rb +11 -63
  19. data/lib/active_record/associations/builder/has_one.rb +47 -45
  20. data/lib/active_record/associations/builder/singular_association.rb +30 -18
  21. data/lib/active_record/associations/collection_association.rb +217 -295
  22. data/lib/active_record/associations/collection_proxy.rb +1074 -77
  23. data/lib/active_record/associations/foreign_association.rb +20 -0
  24. data/lib/active_record/associations/has_many_association.rb +78 -50
  25. data/lib/active_record/associations/has_many_through_association.rb +99 -61
  26. data/lib/active_record/associations/has_one_association.rb +75 -30
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +45 -119
  29. data/lib/active_record/associations/join_dependency/join_base.rb +11 -12
  30. data/lib/active_record/associations/join_dependency/join_part.rb +35 -42
  31. data/lib/active_record/associations/join_dependency.rb +208 -164
  32. data/lib/active_record/associations/preloader/association.rb +93 -87
  33. data/lib/active_record/associations/preloader/through_association.rb +87 -38
  34. data/lib/active_record/associations/preloader.rb +134 -110
  35. data/lib/active_record/associations/singular_association.rb +19 -24
  36. data/lib/active_record/associations/through_association.rb +61 -27
  37. data/lib/active_record/associations.rb +1766 -1505
  38. data/lib/active_record/attribute_assignment.rb +57 -193
  39. data/lib/active_record/attribute_decorators.rb +90 -0
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +58 -8
  41. data/lib/active_record/attribute_methods/dirty.rb +187 -67
  42. data/lib/active_record/attribute_methods/primary_key.rb +100 -78
  43. data/lib/active_record/attribute_methods/query.rb +10 -8
  44. data/lib/active_record/attribute_methods/read.rb +29 -118
  45. data/lib/active_record/attribute_methods/serialization.rb +60 -72
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +69 -42
  47. data/lib/active_record/attribute_methods/write.rb +36 -44
  48. data/lib/active_record/attribute_methods.rb +306 -161
  49. data/lib/active_record/attributes.rb +279 -0
  50. data/lib/active_record/autosave_association.rb +324 -238
  51. data/lib/active_record/base.rb +114 -507
  52. data/lib/active_record/callbacks.rb +147 -83
  53. data/lib/active_record/coders/json.rb +15 -0
  54. data/lib/active_record/coders/yaml_column.rb +32 -23
  55. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +962 -279
  56. data/lib/active_record/connection_adapters/abstract/database_limits.rb +32 -5
  57. data/lib/active_record/connection_adapters/abstract/database_statements.rb +331 -209
  58. data/lib/active_record/connection_adapters/abstract/query_cache.rb +95 -23
  59. data/lib/active_record/connection_adapters/abstract/quoting.rb +201 -65
  60. data/lib/active_record/connection_adapters/abstract/savepoints.rb +23 -0
  61. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -0
  62. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +510 -289
  63. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +93 -0
  64. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +1182 -313
  65. data/lib/active_record/connection_adapters/abstract/transaction.rb +323 -0
  66. data/lib/active_record/connection_adapters/abstract_adapter.rb +585 -120
  67. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +610 -463
  68. data/lib/active_record/connection_adapters/column.rb +58 -233
  69. data/lib/active_record/connection_adapters/connection_specification.rb +297 -0
  70. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
  71. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  72. data/lib/active_record/connection_adapters/mysql/database_statements.rb +200 -0
  73. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
  74. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  79. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  80. data/lib/active_record/connection_adapters/mysql2_adapter.rb +75 -207
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +30 -0
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +182 -0
  83. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +92 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +53 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +15 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +17 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +50 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +23 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +15 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +21 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +71 -0
  94. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +15 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +15 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +41 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +15 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +65 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +97 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +18 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +113 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +26 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +28 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +30 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +34 -0
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +205 -0
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +43 -0
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +222 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +776 -0
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +81 -0
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +695 -1052
  116. data/lib/active_record/connection_adapters/schema_cache.rb +115 -24
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
  119. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  120. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +103 -0
  121. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  125. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +528 -26
  126. data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
  127. data/lib/active_record/connection_handling.rb +267 -0
  128. data/lib/active_record/core.rb +599 -0
  129. data/lib/active_record/counter_cache.rb +177 -103
  130. data/lib/active_record/database_configurations/database_config.rb +37 -0
  131. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  132. data/lib/active_record/database_configurations/url_config.rb +79 -0
  133. data/lib/active_record/database_configurations.rb +233 -0
  134. data/lib/active_record/define_callbacks.rb +22 -0
  135. data/lib/active_record/dynamic_matchers.rb +107 -64
  136. data/lib/active_record/enum.rb +274 -0
  137. data/lib/active_record/errors.rb +254 -61
  138. data/lib/active_record/explain.rb +35 -70
  139. data/lib/active_record/explain_registry.rb +32 -0
  140. data/lib/active_record/explain_subscriber.rb +18 -8
  141. data/lib/active_record/fixture_set/file.rb +82 -0
  142. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  143. data/lib/active_record/fixture_set/render_context.rb +17 -0
  144. data/lib/active_record/fixture_set/table_row.rb +153 -0
  145. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  146. data/lib/active_record/fixtures.rb +291 -475
  147. data/lib/active_record/gem_version.rb +17 -0
  148. data/lib/active_record/inheritance.rb +219 -100
  149. data/lib/active_record/insert_all.rb +179 -0
  150. data/lib/active_record/integration.rb +175 -17
  151. data/lib/active_record/internal_metadata.rb +53 -0
  152. data/lib/active_record/legacy_yaml_adapter.rb +48 -0
  153. data/lib/active_record/locale/en.yml +9 -1
  154. data/lib/active_record/locking/optimistic.rb +106 -92
  155. data/lib/active_record/locking/pessimistic.rb +23 -11
  156. data/lib/active_record/log_subscriber.rb +80 -30
  157. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  158. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  159. data/lib/active_record/middleware/database_selector.rb +75 -0
  160. data/lib/active_record/migration/command_recorder.rb +235 -56
  161. data/lib/active_record/migration/compatibility.rb +244 -0
  162. data/lib/active_record/migration/join_table.rb +17 -0
  163. data/lib/active_record/migration.rb +917 -301
  164. data/lib/active_record/model_schema.rb +351 -175
  165. data/lib/active_record/nested_attributes.rb +366 -235
  166. data/lib/active_record/no_touching.rb +65 -0
  167. data/lib/active_record/null_relation.rb +68 -0
  168. data/lib/active_record/persistence.rb +761 -166
  169. data/lib/active_record/query_cache.rb +22 -44
  170. data/lib/active_record/querying.rb +55 -31
  171. data/lib/active_record/railtie.rb +185 -47
  172. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  173. data/lib/active_record/railties/console_sandbox.rb +5 -4
  174. data/lib/active_record/railties/controller_runtime.rb +35 -33
  175. data/lib/active_record/railties/databases.rake +366 -463
  176. data/lib/active_record/readonly_attributes.rb +4 -6
  177. data/lib/active_record/reflection.rb +736 -228
  178. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  179. data/lib/active_record/relation/batches.rb +252 -52
  180. data/lib/active_record/relation/calculations.rb +340 -270
  181. data/lib/active_record/relation/delegation.rb +117 -36
  182. data/lib/active_record/relation/finder_methods.rb +439 -286
  183. data/lib/active_record/relation/from_clause.rb +26 -0
  184. data/lib/active_record/relation/merger.rb +184 -0
  185. data/lib/active_record/relation/predicate_builder/array_handler.rb +49 -0
  186. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  187. data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
  188. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  189. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  190. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  191. data/lib/active_record/relation/predicate_builder/relation_handler.rb +19 -0
  192. data/lib/active_record/relation/predicate_builder.rb +131 -39
  193. data/lib/active_record/relation/query_attribute.rb +50 -0
  194. data/lib/active_record/relation/query_methods.rb +1163 -221
  195. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  196. data/lib/active_record/relation/spawn_methods.rb +49 -120
  197. data/lib/active_record/relation/where_clause.rb +190 -0
  198. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  199. data/lib/active_record/relation.rb +671 -349
  200. data/lib/active_record/result.rb +149 -15
  201. data/lib/active_record/runtime_registry.rb +24 -0
  202. data/lib/active_record/sanitization.rb +153 -133
  203. data/lib/active_record/schema.rb +22 -19
  204. data/lib/active_record/schema_dumper.rb +178 -112
  205. data/lib/active_record/schema_migration.rb +60 -0
  206. data/lib/active_record/scoping/default.rb +107 -98
  207. data/lib/active_record/scoping/named.rb +130 -115
  208. data/lib/active_record/scoping.rb +77 -123
  209. data/lib/active_record/secure_token.rb +40 -0
  210. data/lib/active_record/serialization.rb +10 -6
  211. data/lib/active_record/statement_cache.rb +148 -0
  212. data/lib/active_record/store.rb +256 -16
  213. data/lib/active_record/suppressor.rb +61 -0
  214. data/lib/active_record/table_metadata.rb +75 -0
  215. data/lib/active_record/tasks/database_tasks.rb +506 -0
  216. data/lib/active_record/tasks/mysql_database_tasks.rb +115 -0
  217. data/lib/active_record/tasks/postgresql_database_tasks.rb +141 -0
  218. data/lib/active_record/tasks/sqlite_database_tasks.rb +77 -0
  219. data/lib/active_record/test_databases.rb +23 -0
  220. data/lib/active_record/test_fixtures.rb +224 -0
  221. data/lib/active_record/timestamp.rb +93 -39
  222. data/lib/active_record/touch_later.rb +66 -0
  223. data/lib/active_record/transactions.rb +260 -129
  224. data/lib/active_record/translation.rb +3 -1
  225. data/lib/active_record/type/adapter_specific_registry.rb +129 -0
  226. data/lib/active_record/type/date.rb +9 -0
  227. data/lib/active_record/type/date_time.rb +9 -0
  228. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  229. data/lib/active_record/type/hash_lookup_type_map.rb +25 -0
  230. data/lib/active_record/type/internal/timezone.rb +17 -0
  231. data/lib/active_record/type/json.rb +30 -0
  232. data/lib/active_record/type/serialized.rb +71 -0
  233. data/lib/active_record/type/text.rb +11 -0
  234. data/lib/active_record/type/time.rb +21 -0
  235. data/lib/active_record/type/type_map.rb +62 -0
  236. data/lib/active_record/type/unsigned_integer.rb +17 -0
  237. data/lib/active_record/type.rb +78 -0
  238. data/lib/active_record/type_caster/connection.rb +34 -0
  239. data/lib/active_record/type_caster/map.rb +20 -0
  240. data/lib/active_record/type_caster.rb +9 -0
  241. data/lib/active_record/validations/absence.rb +25 -0
  242. data/lib/active_record/validations/associated.rb +35 -18
  243. data/lib/active_record/validations/length.rb +26 -0
  244. data/lib/active_record/validations/presence.rb +68 -0
  245. data/lib/active_record/validations/uniqueness.rb +123 -77
  246. data/lib/active_record/validations.rb +54 -43
  247. data/lib/active_record/version.rb +7 -7
  248. data/lib/active_record.rb +97 -49
  249. data/lib/arel/alias_predication.rb +9 -0
  250. data/lib/arel/attributes/attribute.rb +37 -0
  251. data/lib/arel/attributes.rb +22 -0
  252. data/lib/arel/collectors/bind.rb +24 -0
  253. data/lib/arel/collectors/composite.rb +31 -0
  254. data/lib/arel/collectors/plain_string.rb +20 -0
  255. data/lib/arel/collectors/sql_string.rb +20 -0
  256. data/lib/arel/collectors/substitute_binds.rb +28 -0
  257. data/lib/arel/crud.rb +42 -0
  258. data/lib/arel/delete_manager.rb +18 -0
  259. data/lib/arel/errors.rb +9 -0
  260. data/lib/arel/expressions.rb +29 -0
  261. data/lib/arel/factory_methods.rb +49 -0
  262. data/lib/arel/insert_manager.rb +49 -0
  263. data/lib/arel/math.rb +45 -0
  264. data/lib/arel/nodes/and.rb +32 -0
  265. data/lib/arel/nodes/ascending.rb +23 -0
  266. data/lib/arel/nodes/binary.rb +52 -0
  267. data/lib/arel/nodes/bind_param.rb +36 -0
  268. data/lib/arel/nodes/case.rb +55 -0
  269. data/lib/arel/nodes/casted.rb +50 -0
  270. data/lib/arel/nodes/comment.rb +29 -0
  271. data/lib/arel/nodes/count.rb +12 -0
  272. data/lib/arel/nodes/delete_statement.rb +45 -0
  273. data/lib/arel/nodes/descending.rb +23 -0
  274. data/lib/arel/nodes/equality.rb +18 -0
  275. data/lib/arel/nodes/extract.rb +24 -0
  276. data/lib/arel/nodes/false.rb +16 -0
  277. data/lib/arel/nodes/full_outer_join.rb +8 -0
  278. data/lib/arel/nodes/function.rb +44 -0
  279. data/lib/arel/nodes/grouping.rb +8 -0
  280. data/lib/arel/nodes/in.rb +8 -0
  281. data/lib/arel/nodes/infix_operation.rb +80 -0
  282. data/lib/arel/nodes/inner_join.rb +8 -0
  283. data/lib/arel/nodes/insert_statement.rb +37 -0
  284. data/lib/arel/nodes/join_source.rb +20 -0
  285. data/lib/arel/nodes/matches.rb +18 -0
  286. data/lib/arel/nodes/named_function.rb +23 -0
  287. data/lib/arel/nodes/node.rb +50 -0
  288. data/lib/arel/nodes/node_expression.rb +13 -0
  289. data/lib/arel/nodes/outer_join.rb +8 -0
  290. data/lib/arel/nodes/over.rb +15 -0
  291. data/lib/arel/nodes/regexp.rb +16 -0
  292. data/lib/arel/nodes/right_outer_join.rb +8 -0
  293. data/lib/arel/nodes/select_core.rb +67 -0
  294. data/lib/arel/nodes/select_statement.rb +41 -0
  295. data/lib/arel/nodes/sql_literal.rb +16 -0
  296. data/lib/arel/nodes/string_join.rb +11 -0
  297. data/lib/arel/nodes/table_alias.rb +27 -0
  298. data/lib/arel/nodes/terminal.rb +16 -0
  299. data/lib/arel/nodes/true.rb +16 -0
  300. data/lib/arel/nodes/unary.rb +45 -0
  301. data/lib/arel/nodes/unary_operation.rb +20 -0
  302. data/lib/arel/nodes/unqualified_column.rb +22 -0
  303. data/lib/arel/nodes/update_statement.rb +41 -0
  304. data/lib/arel/nodes/values_list.rb +9 -0
  305. data/lib/arel/nodes/window.rb +126 -0
  306. data/lib/arel/nodes/with.rb +11 -0
  307. data/lib/arel/nodes.rb +68 -0
  308. data/lib/arel/order_predications.rb +13 -0
  309. data/lib/arel/predications.rb +257 -0
  310. data/lib/arel/select_manager.rb +271 -0
  311. data/lib/arel/table.rb +110 -0
  312. data/lib/arel/tree_manager.rb +72 -0
  313. data/lib/arel/update_manager.rb +34 -0
  314. data/lib/arel/visitors/depth_first.rb +204 -0
  315. data/lib/arel/visitors/dot.rb +297 -0
  316. data/lib/arel/visitors/ibm_db.rb +34 -0
  317. data/lib/arel/visitors/informix.rb +62 -0
  318. data/lib/arel/visitors/mssql.rb +157 -0
  319. data/lib/arel/visitors/mysql.rb +83 -0
  320. data/lib/arel/visitors/oracle.rb +159 -0
  321. data/lib/arel/visitors/oracle12.rb +66 -0
  322. data/lib/arel/visitors/postgresql.rb +110 -0
  323. data/lib/arel/visitors/sqlite.rb +39 -0
  324. data/lib/arel/visitors/to_sql.rb +889 -0
  325. data/lib/arel/visitors/visitor.rb +46 -0
  326. data/lib/arel/visitors/where_sql.rb +23 -0
  327. data/lib/arel/visitors.rb +20 -0
  328. data/lib/arel/window_predications.rb +9 -0
  329. data/lib/arel.rb +51 -0
  330. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  331. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  332. data/lib/rails/generators/active_record/migration/migration_generator.rb +59 -9
  333. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  334. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +48 -0
  335. data/lib/rails/generators/active_record/migration.rb +41 -8
  336. data/lib/rails/generators/active_record/model/model_generator.rb +24 -22
  337. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  338. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +1 -1
  339. data/lib/rails/generators/active_record.rb +10 -16
  340. metadata +285 -149
  341. data/examples/associations.png +0 -0
  342. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +0 -63
  343. data/lib/active_record/associations/join_helper.rb +0 -55
  344. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  345. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  346. data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +0 -60
  347. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  348. data/lib/active_record/associations/preloader/has_many_through.rb +0 -15
  349. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  350. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  351. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  352. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +0 -32
  353. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +0 -188
  354. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -426
  355. data/lib/active_record/connection_adapters/sqlite_adapter.rb +0 -579
  356. data/lib/active_record/dynamic_finder_match.rb +0 -68
  357. data/lib/active_record/dynamic_scope_match.rb +0 -23
  358. data/lib/active_record/fixtures/file.rb +0 -65
  359. data/lib/active_record/identity_map.rb +0 -162
  360. data/lib/active_record/observer.rb +0 -121
  361. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  362. data/lib/active_record/serializers/xml_serializer.rb +0 -203
  363. data/lib/active_record/session_store.rb +0 -358
  364. data/lib/active_record/test_case.rb +0 -73
  365. data/lib/rails/generators/active_record/migration/templates/migration.rb +0 -34
  366. data/lib/rails/generators/active_record/model/templates/migration.rb +0 -15
  367. data/lib/rails/generators/active_record/model/templates/model.rb +0 -12
  368. data/lib/rails/generators/active_record/observer/observer_generator.rb +0 -15
  369. data/lib/rails/generators/active_record/observer/templates/observer.rb +0 -4
  370. data/lib/rails/generators/active_record/session_migration/session_migration_generator.rb +0 -25
  371. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +0 -12
@@ -1,136 +1,47 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module AttributeMethods
3
5
  module Read
4
6
  extend ActiveSupport::Concern
5
7
 
6
- ATTRIBUTE_TYPES_CACHED_BY_DEFAULT = [:datetime, :timestamp, :time, :date]
7
-
8
- included do
9
- cattr_accessor :attribute_types_cached_by_default, :instance_writer => false
10
- self.attribute_types_cached_by_default = ATTRIBUTE_TYPES_CACHED_BY_DEFAULT
11
- end
12
-
13
- module ClassMethods
14
- # +cache_attributes+ allows you to declare which converted attribute values should
15
- # be cached. Usually caching only pays off for attributes with expensive conversion
16
- # methods, like time related columns (e.g. +created_at+, +updated_at+).
17
- def cache_attributes(*attribute_names)
18
- cached_attributes.merge attribute_names.map { |attr| attr.to_s }
19
- end
20
-
21
- # Returns the attributes which are cached. By default time related columns
22
- # with datatype <tt>:datetime, :timestamp, :time, :date</tt> are cached.
23
- def cached_attributes
24
- @cached_attributes ||= columns.select { |c| cacheable_column?(c) }.map { |col| col.name }.to_set
25
- end
26
-
27
- # Returns +true+ if the provided attribute is being cached.
28
- def cache_attribute?(attr_name)
29
- cached_attributes.include?(attr_name)
30
- end
31
-
32
- def undefine_attribute_methods
33
- generated_external_attribute_methods.module_eval do
34
- instance_methods.each { |m| undef_method(m) }
35
- end
36
-
37
- super
38
- end
39
-
40
- def type_cast_attribute(attr_name, attributes, cache = {}) #:nodoc:
41
- return unless attr_name
42
- attr_name = attr_name.to_s
43
-
44
- if generated_external_attribute_methods.method_defined?(attr_name)
45
- if attributes.has_key?(attr_name) || attr_name == 'id'
46
- generated_external_attribute_methods.send(attr_name, attributes[attr_name], attributes, cache, attr_name)
47
- end
48
- elsif !attribute_methods_generated?
49
- # If we haven't generated the caster methods yet, do that and
50
- # then try again
51
- define_attribute_methods
52
- type_cast_attribute(attr_name, attributes, cache)
53
- else
54
- # If we get here, the attribute has no associated DB column, so
55
- # just return it verbatim.
56
- attributes[attr_name]
57
- end
58
- end
59
-
60
- protected
61
- # We want to generate the methods via module_eval rather than define_method,
62
- # because define_method is slower on dispatch and uses more memory (because it
63
- # creates a closure).
64
- #
65
- # But sometimes the database might return columns with characters that are not
66
- # allowed in normal method names (like 'my_column(omg)'. So to work around this
67
- # we first define with the __temp__ identifier, and then use alias method to
68
- # rename it to what we want.
69
- def define_method_attribute(attr_name)
70
- generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
71
- def __temp__
72
- #{internal_attribute_access_code(attr_name, attribute_cast_code(attr_name))}
73
- end
74
- alias_method '#{attr_name}', :__temp__
75
- undef_method :__temp__
76
- STR
77
- end
78
-
8
+ module ClassMethods # :nodoc:
79
9
  private
80
10
 
81
- def define_external_attribute_method(attr_name)
82
- generated_external_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
83
- def __temp__(v, attributes, attributes_cache, attr_name)
84
- #{external_attribute_access_code(attr_name, attribute_cast_code(attr_name))}
85
- end
86
- alias_method '#{attr_name}', :__temp__
87
- undef_method :__temp__
88
- STR
89
- end
90
-
91
- def cacheable_column?(column)
92
- attribute_types_cached_by_default.include?(column.type)
93
- end
94
-
95
- def internal_attribute_access_code(attr_name, cast_code)
96
- access_code = "(v=@attributes[attr_name]) && #{cast_code}"
97
-
98
- unless attr_name == primary_key
99
- access_code.insert(0, "missing_attribute(attr_name, caller) unless @attributes.has_key?(attr_name); ")
100
- end
101
-
102
- if cache_attribute?(attr_name)
103
- access_code = "@attributes_cache[attr_name] ||= (#{access_code})"
11
+ def define_method_attribute(name)
12
+ ActiveModel::AttributeMethods::AttrNames.define_attribute_accessor_method(
13
+ generated_attribute_methods, name
14
+ ) do |temp_method_name, attr_name_expr|
15
+ generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1
16
+ def #{temp_method_name}
17
+ name = #{attr_name_expr}
18
+ _read_attribute(name) { |n| missing_attribute(n, caller) }
19
+ end
20
+ RUBY
104
21
  end
105
-
106
- "attr_name = '#{attr_name}'; #{access_code}"
107
22
  end
23
+ end
108
24
 
109
- def external_attribute_access_code(attr_name, cast_code)
110
- access_code = "v && #{cast_code}"
111
-
112
- if cache_attribute?(attr_name)
113
- access_code = "attributes_cache[attr_name] ||= (#{access_code})"
114
- end
115
-
116
- access_code
117
- end
25
+ # Returns the value of the attribute identified by <tt>attr_name</tt> after
26
+ # it has been typecast (for example, "2004-12-12" in a date column is cast
27
+ # to a date object, like Date.new(2004, 12, 12)).
28
+ def read_attribute(attr_name, &block)
29
+ name = attr_name.to_s
30
+ name = self.class.attribute_aliases[name] || name
118
31
 
119
- def attribute_cast_code(attr_name)
120
- columns_hash[attr_name].type_cast_code('v')
121
- end
32
+ name = @primary_key if name == "id" && @primary_key
33
+ _read_attribute(name, &block)
122
34
  end
123
35
 
124
- # Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
125
- # "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)).
126
- def read_attribute(attr_name)
127
- self.class.type_cast_attribute(attr_name, @attributes, @attributes_cache)
36
+ # This method exists to avoid the expensive primary_key check internally, without
37
+ # breaking compatibility with the read_attribute API
38
+ def _read_attribute(attr_name, &block) # :nodoc
39
+ sync_with_transaction_state if @transaction_state&.finalized?
40
+ @attributes.fetch_value(attr_name.to_s, &block)
128
41
  end
129
42
 
130
- private
131
- def attribute(attribute_name)
132
- read_attribute(attribute_name)
133
- end
43
+ alias :attribute :_read_attribute
44
+ private :attribute
134
45
  end
135
46
  end
136
47
  end
@@ -1,101 +1,89 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module AttributeMethods
3
5
  module Serialization
4
6
  extend ActiveSupport::Concern
5
7
 
6
- included do
7
- # Returns a hash of all the attributes that have been specified for serialization as
8
- # keys and their class restriction as values.
9
- class_attribute :serialized_attributes
10
- self.serialized_attributes = {}
11
- end
12
-
13
- class Attribute < Struct.new(:coder, :value, :state)
14
- def unserialized_value
15
- state == :serialized ? unserialize : value
16
- end
17
-
18
- def serialized_value
19
- state == :unserialized ? serialize : value
20
- end
21
-
22
- def unserialize
23
- self.state = :unserialized
24
- self.value = coder.load(value)
25
- end
26
-
27
- def serialize
28
- self.state = :serialized
29
- self.value = coder.dump(value)
8
+ class ColumnNotSerializableError < StandardError
9
+ def initialize(name, type)
10
+ super <<~EOS
11
+ Column `#{name}` of type #{type.class} does not support `serialize` feature.
12
+ Usually it means that you are trying to use `serialize`
13
+ on a column that already implements serialization natively.
14
+ EOS
30
15
  end
31
16
  end
32
17
 
33
18
  module ClassMethods
34
- # If you have an attribute that needs to be saved to the database as an object, and retrieved as the same object,
35
- # then specify the name of that attribute using this method and it will be handled automatically.
36
- # The serialization is done through YAML. If +class_name+ is specified, the serialized object must be of that
37
- # class on retrieval or SerializationTypeMismatch will be raised.
19
+ # If you have an attribute that needs to be saved to the database as an
20
+ # object, and retrieved as the same object, then specify the name of that
21
+ # attribute using this method and it will be handled automatically. The
22
+ # serialization is done through YAML. If +class_name+ is specified, the
23
+ # serialized object must be of that class on assignment and retrieval.
24
+ # Otherwise SerializationTypeMismatch will be raised.
25
+ #
26
+ # Empty objects as <tt>{}</tt>, in the case of +Hash+, or <tt>[]</tt>, in the case of
27
+ # +Array+, will always be persisted as null.
28
+ #
29
+ # Keep in mind that database adapters handle certain serialization tasks
30
+ # for you. For instance: +json+ and +jsonb+ types in PostgreSQL will be
31
+ # converted between JSON object/array syntax and Ruby +Hash+ or +Array+
32
+ # objects transparently. There is no need to use #serialize in this
33
+ # case.
34
+ #
35
+ # For more complex cases, such as conversion to or from your application
36
+ # domain objects, consider using the ActiveRecord::Attributes API.
38
37
  #
39
38
  # ==== Parameters
40
39
  #
41
40
  # * +attr_name+ - The field name that should be serialized.
42
- # * +class_name+ - Optional, class name that the object type should be equal to.
41
+ # * +class_name_or_coder+ - Optional, a coder object, which responds to +.load+ and +.dump+
42
+ # or a class name that the object type should be equal to.
43
43
  #
44
44
  # ==== Example
45
- # # Serialize a preferences attribute
45
+ #
46
+ # # Serialize a preferences attribute.
46
47
  # class User < ActiveRecord::Base
47
48
  # serialize :preferences
48
49
  # end
49
- def serialize(attr_name, class_name = Object)
50
- coder = if [:load, :dump].all? { |x| class_name.respond_to?(x) }
51
- class_name
52
- else
53
- Coders::YAMLColumn.new(class_name)
54
- end
55
-
56
- # merge new serialized attribute and create new hash to ensure that each class in inheritance hierarchy
57
- # has its own hash of own serialized attributes
58
- self.serialized_attributes = serialized_attributes.merge(attr_name.to_s => coder)
59
- end
60
-
61
- def initialize_attributes(attributes, options = {}) #:nodoc:
62
- serialized = (options.delete(:serialized) { true }) ? :serialized : :unserialized
63
- super(attributes, options)
50
+ #
51
+ # # Serialize preferences using JSON as coder.
52
+ # class User < ActiveRecord::Base
53
+ # serialize :preferences, JSON
54
+ # end
55
+ #
56
+ # # Serialize preferences as Hash using YAML coder.
57
+ # class User < ActiveRecord::Base
58
+ # serialize :preferences, Hash
59
+ # end
60
+ def serialize(attr_name, class_name_or_coder = Object)
61
+ # When ::JSON is used, force it to go through the Active Support JSON encoder
62
+ # to ensure special objects (e.g. Active Record models) are dumped correctly
63
+ # using the #as_json hook.
64
+ coder = if class_name_or_coder == ::JSON
65
+ Coders::JSON
66
+ elsif [:load, :dump].all? { |x| class_name_or_coder.respond_to?(x) }
67
+ class_name_or_coder
68
+ else
69
+ Coders::YAMLColumn.new(attr_name, class_name_or_coder)
70
+ end
64
71
 
65
- serialized_attributes.each do |key, coder|
66
- if attributes.key?(key)
67
- attributes[key] = Attribute.new(coder, attributes[key], serialized)
72
+ decorate_attribute_type(attr_name, :serialize) do |type|
73
+ if type_incompatible_with_serialize?(type, class_name_or_coder)
74
+ raise ColumnNotSerializableError.new(attr_name, type)
68
75
  end
69
- end
70
76
 
71
- attributes
77
+ Type::Serialized.new(type, coder)
78
+ end
72
79
  end
73
80
 
74
81
  private
75
82
 
76
- def attribute_cast_code(attr_name)
77
- if serialized_attributes.include?(attr_name)
78
- "v.unserialized_value"
79
- else
80
- super
83
+ def type_incompatible_with_serialize?(type, class_name)
84
+ type.is_a?(ActiveRecord::Type::Json) && class_name == ::JSON ||
85
+ type.respond_to?(:type_cast_array, true) && class_name == ::Array
81
86
  end
82
- end
83
- end
84
-
85
- def type_cast_attribute_for_write(column, value)
86
- if column && coder = self.class.serialized_attributes[column.name]
87
- Attribute.new(coder, value, :unserialized)
88
- else
89
- super
90
- end
91
- end
92
-
93
- def read_attribute_before_type_cast(attr_name)
94
- if serialized_attributes.include?(attr_name)
95
- super.unserialized_value
96
- else
97
- super
98
- end
99
87
  end
100
88
  end
101
89
  end
@@ -1,62 +1,89 @@
1
- require 'active_support/core_ext/class/attribute'
2
- require 'active_support/core_ext/object/inclusion'
1
+ # frozen_string_literal: true
3
2
 
4
3
  module ActiveRecord
5
4
  module AttributeMethods
6
5
  module TimeZoneConversion
7
- extend ActiveSupport::Concern
6
+ class TimeZoneConverter < DelegateClass(Type::Value) # :nodoc:
7
+ def deserialize(value)
8
+ convert_time_to_time_zone(super)
9
+ end
8
10
 
9
- included do
10
- cattr_accessor :time_zone_aware_attributes, :instance_writer => false
11
- self.time_zone_aware_attributes = false
11
+ def cast(value)
12
+ return if value.nil?
12
13
 
13
- class_attribute :skip_time_zone_conversion_for_attributes, :instance_writer => false
14
- self.skip_time_zone_conversion_for_attributes = []
15
- end
14
+ if value.is_a?(Hash)
15
+ set_time_zone_without_conversion(super)
16
+ elsif value.respond_to?(:in_time_zone)
17
+ begin
18
+ super(user_input_in_time_zone(value)) || super
19
+ rescue ArgumentError
20
+ nil
21
+ end
22
+ else
23
+ map_avoiding_infinite_recursion(super) { |v| cast(v) }
24
+ end
25
+ end
16
26
 
17
- module ClassMethods
18
- protected
19
- # The enhanced read method automatically converts the UTC time stored in the database to the time
20
- # zone stored in Time.zone.
21
- def attribute_cast_code(attr_name)
22
- column = columns_hash[attr_name]
27
+ private
23
28
 
24
- if create_time_zone_conversion_attribute?(attr_name, column)
25
- typecast = "v = #{super}"
26
- time_zone_conversion = "v.acts_like?(:time) ? v.in_time_zone : v"
29
+ def convert_time_to_time_zone(value)
30
+ return if value.nil?
27
31
 
28
- "((#{typecast}) && (#{time_zone_conversion}))"
32
+ if value.acts_like?(:time)
33
+ value.in_time_zone
34
+ elsif value.is_a?(::Float)
35
+ value
29
36
  else
30
- super
37
+ map_avoiding_infinite_recursion(value) { |v| convert_time_to_time_zone(v) }
31
38
  end
32
39
  end
33
40
 
34
- # Defined for all +datetime+ and +timestamp+ attributes when +time_zone_aware_attributes+ are enabled.
35
- # This enhanced write method will automatically convert the time passed to it to the zone stored in Time.zone.
36
- def define_method_attribute=(attr_name)
37
- if create_time_zone_conversion_attribute?(attr_name, columns_hash[attr_name])
38
- method_body, line = <<-EOV, __LINE__ + 1
39
- def #{attr_name}=(original_time)
40
- time = original_time
41
- unless time.acts_like?(:time)
42
- time = time.is_a?(String) ? Time.zone.parse(time) : time.to_time rescue time
43
- end
44
- time = time.in_time_zone rescue nil if time
45
- changed = read_attribute(:#{attr_name}) != time
46
- write_attribute(:#{attr_name}, original_time)
47
- #{attr_name}_will_change! if changed
48
- @attributes_cache["#{attr_name}"] = time
49
- end
50
- EOV
51
- generated_attribute_methods.module_eval(method_body, __FILE__, line)
52
- else
53
- super
41
+ def set_time_zone_without_conversion(value)
42
+ ::Time.zone.local_to_utc(value).try(:in_time_zone) if value
43
+ end
44
+
45
+ def map_avoiding_infinite_recursion(value)
46
+ map(value) do |v|
47
+ if value.equal?(v)
48
+ nil
49
+ else
50
+ yield(v)
51
+ end
54
52
  end
55
53
  end
54
+ end
56
55
 
56
+ extend ActiveSupport::Concern
57
+
58
+ included do
59
+ mattr_accessor :time_zone_aware_attributes, instance_writer: false, default: false
60
+
61
+ class_attribute :skip_time_zone_conversion_for_attributes, instance_writer: false, default: []
62
+ class_attribute :time_zone_aware_types, instance_writer: false, default: [ :datetime, :time ]
63
+ end
64
+
65
+ module ClassMethods # :nodoc:
57
66
  private
58
- def create_time_zone_conversion_attribute?(name, column)
59
- time_zone_aware_attributes && !self.skip_time_zone_conversion_for_attributes.include?(name.to_sym) && column.type.in?([:datetime, :timestamp])
67
+
68
+ def inherited(subclass)
69
+ super
70
+ # We need to apply this decorator here, rather than on module inclusion. The closure
71
+ # created by the matcher would otherwise evaluate for `ActiveRecord::Base`, not the
72
+ # sub class being decorated. As such, changes to `time_zone_aware_attributes`, or
73
+ # `skip_time_zone_conversion_for_attributes` would not be picked up.
74
+ subclass.class_eval do
75
+ matcher = ->(name, type) { create_time_zone_conversion_attribute?(name, type) }
76
+ decorate_matching_attribute_types(matcher, "_time_zone_conversion") do |type|
77
+ TimeZoneConverter.new(type)
78
+ end
79
+ end
80
+ end
81
+
82
+ def create_time_zone_conversion_attribute?(name, cast_type)
83
+ enabled_for_column = time_zone_aware_attributes &&
84
+ !skip_time_zone_conversion_for_attributes.include?(name.to_sym)
85
+
86
+ enabled_for_column && time_zone_aware_types.include?(cast_type.type)
60
87
  end
61
88
  end
62
89
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module AttributeMethods
3
5
  module Write
@@ -7,62 +9,52 @@ module ActiveRecord
7
9
  attribute_method_suffix "="
8
10
  end
9
11
 
10
- module ClassMethods
11
- protected
12
- def define_method_attribute=(attr_name)
13
- if attr_name =~ ActiveModel::AttributeMethods::NAME_COMPILABLE_REGEXP
14
- generated_attribute_methods.module_eval("def #{attr_name}=(new_value); write_attribute('#{attr_name}', new_value); end", __FILE__, __LINE__)
15
- else
16
- generated_attribute_methods.send(:define_method, "#{attr_name}=") do |new_value|
17
- write_attribute(attr_name, new_value)
18
- end
12
+ module ClassMethods # :nodoc:
13
+ private
14
+
15
+ def define_method_attribute=(name)
16
+ ActiveModel::AttributeMethods::AttrNames.define_attribute_accessor_method(
17
+ generated_attribute_methods, name, writer: true,
18
+ ) do |temp_method_name, attr_name_expr|
19
+ generated_attribute_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1
20
+ def #{temp_method_name}(value)
21
+ name = #{attr_name_expr}
22
+ _write_attribute(name, value)
23
+ end
24
+ RUBY
19
25
  end
20
26
  end
21
27
  end
22
28
 
23
- # Updates the attribute identified by <tt>attr_name</tt> with the specified +value+. Empty strings
24
- # for fixnum and float columns are turned into +nil+.
29
+ # Updates the attribute identified by <tt>attr_name</tt> with the
30
+ # specified +value+. Empty strings for Integer and Float columns are
31
+ # turned into +nil+.
25
32
  def write_attribute(attr_name, value)
26
- attr_name = attr_name.to_s
27
- attr_name = self.class.primary_key if attr_name == 'id' && self.class.primary_key
28
- @attributes_cache.delete(attr_name)
29
- column = column_for_attribute(attr_name)
33
+ name = attr_name.to_s
34
+ name = self.class.attribute_aliases[name] || name
30
35
 
31
- unless column || @attributes.has_key?(attr_name)
32
- ActiveSupport::Deprecation.warn(
33
- "You're trying to create an attribute `#{attr_name}'. Writing arbitrary " \
34
- "attributes on a model is deprecated. Please just use `attr_writer` etc."
35
- )
36
- end
36
+ name = @primary_key if name == "id" && @primary_key
37
+ _write_attribute(name, value)
38
+ end
37
39
 
38
- @attributes[attr_name] = type_cast_attribute_for_write(column, value)
40
+ # This method exists to avoid the expensive primary_key check internally, without
41
+ # breaking compatibility with the write_attribute API
42
+ def _write_attribute(attr_name, value) # :nodoc:
43
+ sync_with_transaction_state if @transaction_state&.finalized?
44
+ @attributes.write_from_user(attr_name.to_s, value)
45
+ value
39
46
  end
40
- alias_method :raw_write_attribute, :write_attribute
41
47
 
42
48
  private
43
- # Handle *= for method_missing.
44
- def attribute=(attribute_name, value)
45
- write_attribute(attribute_name, value)
49
+ def write_attribute_without_type_cast(attr_name, value)
50
+ sync_with_transaction_state if @transaction_state&.finalized?
51
+ @attributes.write_cast_value(attr_name.to_s, value)
52
+ value
46
53
  end
47
54
 
48
- def type_cast_attribute_for_write(column, value)
49
- if column && column.number?
50
- convert_number_column_value(value)
51
- else
52
- value
53
- end
54
- end
55
-
56
- def convert_number_column_value(value)
57
- if value == false
58
- 0
59
- elsif value == true
60
- 1
61
- elsif value.is_a?(String) && value.blank?
62
- nil
63
- else
64
- value
65
- end
55
+ # Dispatch target for <tt>*=</tt> attribute methods.
56
+ def attribute=(attribute_name, value)
57
+ _write_attribute(attribute_name, value)
66
58
  end
67
59
  end
68
60
  end