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,101 +1,221 @@
1
- require 'active_support/core_ext/class/attribute'
2
- require 'active_support/core_ext/object/blank'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/attribute_accessors"
3
4
 
4
5
  module ActiveRecord
5
6
  module AttributeMethods
6
7
  module Dirty
7
8
  extend ActiveSupport::Concern
9
+
8
10
  include ActiveModel::Dirty
9
- include AttributeMethods::Write
10
11
 
11
12
  included do
12
13
  if self < ::ActiveRecord::Timestamp
13
14
  raise "You cannot include Dirty after Timestamp"
14
15
  end
15
16
 
16
- class_attribute :partial_updates
17
- self.partial_updates = true
18
- end
17
+ class_attribute :partial_writes, instance_writer: false, default: true
19
18
 
20
- # Attempts to +save+ the record and clears changed attributes if successful.
21
- def save(*) #:nodoc:
22
- if status = super
23
- @previously_changed = changes
24
- @changed_attributes.clear
25
- elsif IdentityMap.enabled?
26
- IdentityMap.remove(self)
27
- end
28
- status
29
- end
19
+ # Attribute methods for "changed in last call to save?"
20
+ attribute_method_affix(prefix: "saved_change_to_", suffix: "?")
21
+ attribute_method_prefix("saved_change_to_")
22
+ attribute_method_suffix("_before_last_save")
30
23
 
31
- # Attempts to <tt>save!</tt> the record and clears changed attributes if successful.
32
- def save!(*) #:nodoc:
33
- super.tap do
34
- @previously_changed = changes
35
- @changed_attributes.clear
36
- end
37
- rescue
38
- IdentityMap.remove(self) if IdentityMap.enabled?
39
- raise
24
+ # Attribute methods for "will change if I call save?"
25
+ attribute_method_affix(prefix: "will_save_change_to_", suffix: "?")
26
+ attribute_method_suffix("_change_to_be_saved", "_in_database")
40
27
  end
41
28
 
42
29
  # <tt>reload</tt> the record and clears changed attributes.
43
- def reload(*) #:nodoc:
30
+ def reload(*)
44
31
  super.tap do
45
- @previously_changed.clear
46
- @changed_attributes.clear
32
+ @mutations_before_last_save = nil
33
+ @mutations_from_database = nil
47
34
  end
48
35
  end
49
36
 
50
- private
51
- # Wrap write_attribute to remember original attribute value.
52
- def write_attribute(attr, value)
53
- attr = attr.to_s
54
-
55
- # The attribute already has an unsaved change.
56
- if attribute_changed?(attr)
57
- old = @changed_attributes[attr]
58
- @changed_attributes.delete(attr) unless field_changed?(attr, old, value)
59
- else
60
- old = clone_attribute_value(:read_attribute, attr)
61
- # Save Time objects as TimeWithZone if time_zone_aware_attributes == true
62
- old = old.in_time_zone if clone_with_time_zone_conversion_attribute?(attr, old)
63
- @changed_attributes[attr] = old if field_changed?(attr, old, value)
64
- end
37
+ # Did this attribute change when we last saved?
38
+ #
39
+ # This method is useful in after callbacks to determine if an attribute
40
+ # was changed during the save that triggered the callbacks to run. It can
41
+ # be invoked as +saved_change_to_name?+ instead of
42
+ # <tt>saved_change_to_attribute?("name")</tt>.
43
+ #
44
+ # ==== Options
45
+ #
46
+ # +from+ When passed, this method will return false unless the original
47
+ # value is equal to the given option
48
+ #
49
+ # +to+ When passed, this method will return false unless the value was
50
+ # changed to the given value
51
+ def saved_change_to_attribute?(attr_name, **options)
52
+ mutations_before_last_save.changed?(attr_name.to_s, options)
53
+ end
54
+
55
+ # Returns the change to an attribute during the last save. If the
56
+ # attribute was changed, the result will be an array containing the
57
+ # original value and the saved value.
58
+ #
59
+ # This method is useful in after callbacks, to see the change in an
60
+ # attribute during the save that triggered the callbacks to run. It can be
61
+ # invoked as +saved_change_to_name+ instead of
62
+ # <tt>saved_change_to_attribute("name")</tt>.
63
+ def saved_change_to_attribute(attr_name)
64
+ mutations_before_last_save.change_to_attribute(attr_name.to_s)
65
+ end
66
+
67
+ # Returns the original value of an attribute before the last save.
68
+ #
69
+ # This method is useful in after callbacks to get the original value of an
70
+ # attribute before the save that triggered the callbacks to run. It can be
71
+ # invoked as +name_before_last_save+ instead of
72
+ # <tt>attribute_before_last_save("name")</tt>.
73
+ def attribute_before_last_save(attr_name)
74
+ mutations_before_last_save.original_value(attr_name.to_s)
75
+ end
76
+
77
+ # Did the last call to +save+ have any changes to change?
78
+ def saved_changes?
79
+ mutations_before_last_save.any_changes?
80
+ end
81
+
82
+ # Returns a hash containing all the changes that were just saved.
83
+ def saved_changes
84
+ mutations_before_last_save.changes
85
+ end
86
+
87
+ # Will this attribute change the next time we save?
88
+ #
89
+ # This method is useful in validations and before callbacks to determine
90
+ # if the next call to +save+ will change a particular attribute. It can be
91
+ # invoked as +will_save_change_to_name?+ instead of
92
+ # <tt>will_save_change_to_attribute("name")</tt>.
93
+ #
94
+ # ==== Options
95
+ #
96
+ # +from+ When passed, this method will return false unless the original
97
+ # value is equal to the given option
98
+ #
99
+ # +to+ When passed, this method will return false unless the value will be
100
+ # changed to the given value
101
+ def will_save_change_to_attribute?(attr_name, **options)
102
+ mutations_from_database.changed?(attr_name.to_s, options)
103
+ end
104
+
105
+ # Returns the change to an attribute that will be persisted during the
106
+ # next save.
107
+ #
108
+ # This method is useful in validations and before callbacks, to see the
109
+ # change to an attribute that will occur when the record is saved. It can
110
+ # be invoked as +name_change_to_be_saved+ instead of
111
+ # <tt>attribute_change_to_be_saved("name")</tt>.
112
+ #
113
+ # If the attribute will change, the result will be an array containing the
114
+ # original value and the new value about to be saved.
115
+ def attribute_change_to_be_saved(attr_name)
116
+ mutations_from_database.change_to_attribute(attr_name.to_s)
117
+ end
118
+
119
+ # Returns the value of an attribute in the database, as opposed to the
120
+ # in-memory value that will be persisted the next time the record is
121
+ # saved.
122
+ #
123
+ # This method is useful in validations and before callbacks, to see the
124
+ # original value of an attribute prior to any changes about to be
125
+ # saved. It can be invoked as +name_in_database+ instead of
126
+ # <tt>attribute_in_database("name")</tt>.
127
+ def attribute_in_database(attr_name)
128
+ mutations_from_database.original_value(attr_name.to_s)
129
+ end
130
+
131
+ # Will the next call to +save+ have any changes to persist?
132
+ def has_changes_to_save?
133
+ mutations_from_database.any_changes?
134
+ end
135
+
136
+ # Returns a hash containing all the changes that will be persisted during
137
+ # the next save.
138
+ def changes_to_save
139
+ mutations_from_database.changes
140
+ end
65
141
 
66
- # Carry on.
67
- super(attr, value)
142
+ # Returns an array of the names of any attributes that will change when
143
+ # the record is next saved.
144
+ def changed_attribute_names_to_save
145
+ mutations_from_database.changed_attribute_names
68
146
  end
69
147
 
70
- def update(*)
71
- if partial_updates?
72
- # Serialized attributes should always be written in case they've been
73
- # changed in place.
74
- super(changed | (attributes.keys & self.class.serialized_attributes.keys))
75
- else
148
+ # Returns a hash of the attributes that will change when the record is
149
+ # next saved.
150
+ #
151
+ # The hash keys are the attribute names, and the hash values are the
152
+ # original attribute values in the database (as opposed to the in-memory
153
+ # values about to be saved).
154
+ def attributes_in_database
155
+ mutations_from_database.changed_values
156
+ end
157
+
158
+ private
159
+ def mutations_from_database
160
+ sync_with_transaction_state if @transaction_state&.finalized?
76
161
  super
77
162
  end
78
- end
79
163
 
80
- def field_changed?(attr, old, value)
81
- if column = column_for_attribute(attr)
82
- if column.number? && column.null && (old.nil? || old == 0) && value.blank?
83
- # For nullable numeric columns, NULL gets stored in database for blank (i.e. '') values.
84
- # Hence we don't record it as a change if the value changes from nil to ''.
85
- # If an old value of 0 is set to '' we want this to get changed to nil as otherwise it'll
86
- # be typecast back to 0 (''.to_i => 0)
87
- value = nil
88
- else
89
- value = column.type_cast(value)
164
+ def mutations_before_last_save
165
+ sync_with_transaction_state if @transaction_state&.finalized?
166
+ super
167
+ end
168
+
169
+ def write_attribute_without_type_cast(attr_name, value)
170
+ result = super
171
+ clear_attribute_change(attr_name)
172
+ result
173
+ end
174
+
175
+ def _touch_row(attribute_names, time)
176
+ @_touch_attr_names = Set.new(attribute_names)
177
+
178
+ affected_rows = super
179
+
180
+ if @_skip_dirty_tracking ||= false
181
+ clear_attribute_changes(@_touch_attr_names)
182
+ return affected_rows
183
+ end
184
+
185
+ changes = {}
186
+ @attributes.keys.each do |attr_name|
187
+ next if @_touch_attr_names.include?(attr_name)
188
+
189
+ if attribute_changed?(attr_name)
190
+ changes[attr_name] = _read_attribute(attr_name)
191
+ _write_attribute(attr_name, attribute_was(attr_name))
192
+ clear_attribute_change(attr_name)
193
+ end
90
194
  end
195
+
196
+ changes_applied
197
+ changes.each { |attr_name, value| _write_attribute(attr_name, value) }
198
+
199
+ affected_rows
200
+ ensure
201
+ @_touch_attr_names, @_skip_dirty_tracking = nil, nil
91
202
  end
92
203
 
93
- old != value
94
- end
204
+ def _update_record(attribute_names = attribute_names_for_partial_writes)
205
+ affected_rows = super
206
+ changes_applied
207
+ affected_rows
208
+ end
95
209
 
96
- def clone_with_time_zone_conversion_attribute?(attr, old)
97
- old.class.name == "Time" && time_zone_aware_attributes && !self.skip_time_zone_conversion_for_attributes.include?(attr.to_sym)
98
- end
210
+ def _create_record(attribute_names = attribute_names_for_partial_writes)
211
+ id = super
212
+ changes_applied
213
+ id
214
+ end
215
+
216
+ def attribute_names_for_partial_writes
217
+ partial_writes? ? changed_attribute_names_to_save : attribute_names
218
+ end
99
219
  end
100
220
  end
101
221
  end
@@ -1,114 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
4
+
1
5
  module ActiveRecord
2
6
  module AttributeMethods
3
7
  module PrimaryKey
4
8
  extend ActiveSupport::Concern
5
9
 
6
- # Returns this record's primary key value wrapped in an Array if one is available
10
+ # Returns this record's primary key value wrapped in an array if one is
11
+ # available.
7
12
  def to_key
8
- key = self.id
13
+ key = id
9
14
  [key] if key
10
15
  end
11
16
 
12
- # Returns the primary key value
17
+ # Returns the primary key column's value.
13
18
  def id
14
- read_attribute(self.class.primary_key)
19
+ _read_attribute(@primary_key)
15
20
  end
16
21
 
17
- # Sets the primary key value
22
+ # Sets the primary key column's value.
18
23
  def id=(value)
19
- write_attribute(self.class.primary_key, value)
24
+ _write_attribute(@primary_key, value)
20
25
  end
21
26
 
22
- # Queries the primary key value
27
+ # Queries the primary key column's value.
23
28
  def id?
24
- query_attribute(self.class.primary_key)
29
+ query_attribute(@primary_key)
25
30
  end
26
31
 
27
- module ClassMethods
28
- def define_method_attribute(attr_name)
29
- super
32
+ # Returns the primary key column's value before type cast.
33
+ def id_before_type_cast
34
+ read_attribute_before_type_cast(@primary_key)
35
+ end
30
36
 
31
- if attr_name == primary_key && attr_name != 'id'
32
- generated_attribute_methods.send(:alias_method, :id, primary_key)
33
- generated_external_attribute_methods.module_eval <<-CODE, __FILE__, __LINE__
34
- def id(v, attributes, attributes_cache, attr_name)
35
- attr_name = '#{primary_key}'
36
- send(attr_name, attributes[attr_name], attributes, attributes_cache, attr_name)
37
- end
38
- CODE
39
- end
40
- end
37
+ # Returns the primary key column's previous value.
38
+ def id_was
39
+ attribute_was(@primary_key)
40
+ end
41
41
 
42
- def dangerous_attribute_method?(method_name)
43
- super && !['id', 'id=', 'id?'].include?(method_name)
44
- end
42
+ # Returns the primary key column's value from the database.
43
+ def id_in_database
44
+ attribute_in_database(@primary_key)
45
+ end
45
46
 
46
- # Defines the primary key field -- can be overridden in subclasses. Overwriting will negate any effect of the
47
- # primary_key_prefix_type setting, though.
48
- def primary_key
49
- @primary_key = reset_primary_key unless defined? @primary_key
50
- @primary_key
51
- end
47
+ private
52
48
 
53
- # Returns a quoted version of the primary key name, used to construct SQL statements.
54
- def quoted_primary_key
55
- @quoted_primary_key ||= connection.quote_column_name(primary_key)
49
+ def attribute_method?(attr_name)
50
+ attr_name == "id" || super
56
51
  end
57
52
 
58
- def reset_primary_key #:nodoc:
59
- if self == base_class
60
- self.primary_key = get_primary_key(base_class.name)
61
- else
62
- self.primary_key = base_class.primary_key
53
+ module ClassMethods
54
+ ID_ATTRIBUTE_METHODS = %w(id id= id? id_before_type_cast id_was id_in_database).to_set
55
+
56
+ def instance_method_already_implemented?(method_name)
57
+ super || primary_key && ID_ATTRIBUTE_METHODS.include?(method_name)
58
+ end
59
+
60
+ def dangerous_attribute_method?(method_name)
61
+ super && !ID_ATTRIBUTE_METHODS.include?(method_name)
62
+ end
63
+
64
+ # Defines the primary key field -- can be overridden in subclasses.
65
+ # Overwriting will negate any effect of the +primary_key_prefix_type+
66
+ # setting, though.
67
+ def primary_key
68
+ @primary_key = reset_primary_key unless defined? @primary_key
69
+ @primary_key
63
70
  end
64
- end
65
71
 
66
- def get_primary_key(base_name) #:nodoc:
67
- return 'id' unless base_name && !base_name.blank?
68
-
69
- case primary_key_prefix_type
70
- when :table_name
71
- base_name.foreign_key(false)
72
- when :table_name_with_underscore
73
- base_name.foreign_key
74
- else
75
- if ActiveRecord::Base != self && table_exists?
76
- connection.schema_cache.primary_keys[table_name]
72
+ # Returns a quoted version of the primary key name, used to construct
73
+ # SQL statements.
74
+ def quoted_primary_key
75
+ @quoted_primary_key ||= connection.quote_column_name(primary_key)
76
+ end
77
+
78
+ def reset_primary_key #:nodoc:
79
+ if base_class?
80
+ self.primary_key = get_primary_key(base_class.name)
77
81
  else
78
- 'id'
82
+ self.primary_key = base_class.primary_key
79
83
  end
80
84
  end
81
- end
82
85
 
83
- def original_primary_key #:nodoc:
84
- deprecated_original_property_getter :primary_key
85
- end
86
+ def get_primary_key(base_name) #:nodoc:
87
+ if base_name && primary_key_prefix_type == :table_name
88
+ base_name.foreign_key(false)
89
+ elsif base_name && primary_key_prefix_type == :table_name_with_underscore
90
+ base_name.foreign_key
91
+ else
92
+ if ActiveRecord::Base != self && table_exists?
93
+ pk = connection.schema_cache.primary_keys(table_name)
94
+ suppress_composite_primary_key(pk)
95
+ else
96
+ "id"
97
+ end
98
+ end
99
+ end
86
100
 
87
- # Sets the name of the primary key column.
88
- #
89
- # class Project < ActiveRecord::Base
90
- # self.primary_key = "sysid"
91
- # end
92
- #
93
- # You can also define the primary_key method yourself:
94
- #
95
- # class Project < ActiveRecord::Base
96
- # def self.primary_key
97
- # "foo_" + super
98
- # end
99
- # end
100
- # Project.primary_key # => "foo_id"
101
- def primary_key=(value)
102
- @original_primary_key = @primary_key if defined?(@primary_key)
103
- @primary_key = value && value.to_s
104
- @quoted_primary_key = nil
105
- end
101
+ # Sets the name of the primary key column.
102
+ #
103
+ # class Project < ActiveRecord::Base
104
+ # self.primary_key = 'sysid'
105
+ # end
106
+ #
107
+ # You can also define the #primary_key method yourself:
108
+ #
109
+ # class Project < ActiveRecord::Base
110
+ # def self.primary_key
111
+ # 'foo_' + super
112
+ # end
113
+ # end
114
+ #
115
+ # Project.primary_key # => "foo_id"
116
+ def primary_key=(value)
117
+ @primary_key = value && -value.to_s
118
+ @quoted_primary_key = nil
119
+ @attributes_builder = nil
120
+ end
121
+
122
+ private
123
+
124
+ def suppress_composite_primary_key(pk)
125
+ return pk unless pk.is_a?(Array)
106
126
 
107
- def set_primary_key(value = nil, &block) #:nodoc:
108
- deprecated_property_setter :primary_key, value, block
109
- @quoted_primary_key = nil
127
+ warn <<~WARNING
128
+ WARNING: Active Record does not support composite primary key.
129
+
130
+ #{table_name} has composite primary key. Composite primary key is ignored.
131
+ WARNING
132
+ end
110
133
  end
111
- end
112
134
  end
113
135
  end
114
136
  end
@@ -1,4 +1,4 @@
1
- require 'active_support/core_ext/object/blank'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecord
4
4
  module AttributeMethods
@@ -10,18 +10,20 @@ module ActiveRecord
10
10
  end
11
11
 
12
12
  def query_attribute(attr_name)
13
- unless value = read_attribute(attr_name)
14
- false
13
+ value = self[attr_name]
14
+
15
+ case value
16
+ when true then true
17
+ when false, nil then false
15
18
  else
16
- column = self.class.columns_hash[attr_name]
17
- if column.nil?
19
+ if !type_for_attribute(attr_name) { false }
18
20
  if Numeric === value || value !~ /[^0-9]/
19
21
  !value.to_i.zero?
20
22
  else
21
- return false if ActiveRecord::ConnectionAdapters::Column::FALSE_VALUES.include?(value)
23
+ return false if ActiveModel::Type::Boolean::FALSE_VALUES.include?(value)
22
24
  !value.blank?
23
25
  end
24
- elsif column.number?
26
+ elsif value.respond_to?(:zero?)
25
27
  !value.zero?
26
28
  else
27
29
  !value.blank?
@@ -30,7 +32,7 @@ module ActiveRecord
30
32
  end
31
33
 
32
34
  private
33
- # Handle *? for method_missing.
35
+ # Dispatch target for <tt>*?</tt> attribute methods.
34
36
  def attribute?(attribute_name)
35
37
  query_attribute(attribute_name)
36
38
  end