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,8 +1,10 @@
1
- require 'active_support/core_ext/module/attribute_accessors'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/attribute_accessors"
2
4
 
3
5
  module ActiveRecord
4
6
  module AttributeMethods
5
- module Dirty # :nodoc:
7
+ module Dirty
6
8
  extend ActiveSupport::Concern
7
9
 
8
10
  include ActiveModel::Dirty
@@ -12,170 +14,208 @@ module ActiveRecord
12
14
  raise "You cannot include Dirty after Timestamp"
13
15
  end
14
16
 
15
- class_attribute :partial_writes, instance_writer: false
16
- self.partial_writes = true
17
- end
17
+ class_attribute :partial_writes, instance_writer: false, default: true
18
18
 
19
- # Attempts to +save+ the record and clears changed attributes if successful.
20
- def save(*)
21
- if status = super
22
- changes_applied
23
- end
24
- status
25
- 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")
26
23
 
27
- # Attempts to <tt>save!</tt> the record and clears changed attributes if successful.
28
- def save!(*)
29
- super.tap do
30
- changes_applied
31
- end
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")
32
27
  end
33
28
 
34
29
  # <tt>reload</tt> the record and clears changed attributes.
35
30
  def reload(*)
36
31
  super.tap do
37
- clear_changes_information
32
+ @mutations_before_last_save = nil
33
+ @mutations_from_database = nil
38
34
  end
39
35
  end
40
36
 
41
- def initialize_dup(other) # :nodoc:
42
- super
43
- calculate_changes_from_defaults
44
- end
45
-
46
- def changes_applied
47
- super
48
- store_original_raw_attributes
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
141
+
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
146
+ end
147
+
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
49
156
  end
50
157
 
51
- def clear_changes_information
52
- super
53
- original_raw_attributes.clear
54
- end
55
-
56
- def changed_attributes
57
- # This should only be set by methods which will call changed_attributes
58
- # multiple times when it is known that the computed value cannot change.
59
- if defined?(@cached_changed_attributes)
60
- @cached_changed_attributes
61
- else
62
- super.reverse_merge(attributes_changed_in_place).freeze
158
+ private
159
+ def mutations_from_database
160
+ sync_with_transaction_state if @transaction_state&.finalized?
161
+ super
63
162
  end
64
- end
65
163
 
66
- def changes
67
- cache_changed_attributes do
164
+ def mutations_before_last_save
165
+ sync_with_transaction_state if @transaction_state&.finalized?
68
166
  super
69
167
  end
70
- end
71
-
72
- def attribute_changed_in_place?(attr_name)
73
- old_value = original_raw_attribute(attr_name)
74
- @attributes[attr_name].changed_in_place_from?(old_value)
75
- end
76
-
77
- private
78
168
 
79
- def calculate_changes_from_defaults
80
- @changed_attributes = nil
81
- self.class.column_defaults.each do |attr, orig_value|
82
- set_attribute_was(attr, orig_value) if _field_changed?(attr, orig_value)
169
+ def write_attribute_without_type_cast(attr_name, value)
170
+ result = super
171
+ clear_attribute_change(attr_name)
172
+ result
83
173
  end
84
- end
85
174
 
86
- # Wrap write_attribute to remember original attribute value.
87
- def write_attribute(attr, value)
88
- attr = attr.to_s
175
+ def _touch_row(attribute_names, time)
176
+ @_touch_attr_names = Set.new(attribute_names)
89
177
 
90
- old_value = old_attribute_value(attr)
178
+ affected_rows = super
91
179
 
92
- result = super
93
- store_original_raw_attribute(attr)
94
- save_changed_attribute(attr, old_value)
95
- result
96
- end
180
+ if @_skip_dirty_tracking ||= false
181
+ clear_attribute_changes(@_touch_attr_names)
182
+ return affected_rows
183
+ end
97
184
 
98
- def raw_write_attribute(attr, value)
99
- attr = attr.to_s
185
+ changes = {}
186
+ @attributes.keys.each do |attr_name|
187
+ next if @_touch_attr_names.include?(attr_name)
100
188
 
101
- result = super
102
- original_raw_attributes[attr] = value
103
- result
104
- end
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
194
+ end
105
195
 
106
- def save_changed_attribute(attr, old_value)
107
- if attribute_changed?(attr)
108
- clear_attribute_changes(attr) unless _field_changed?(attr, old_value)
109
- else
110
- set_attribute_was(attr, old_value) if _field_changed?(attr, old_value)
111
- end
112
- end
113
-
114
- def old_attribute_value(attr)
115
- if attribute_changed?(attr)
116
- changed_attributes[attr]
117
- else
118
- clone_attribute_value(:_read_attribute, attr)
119
- end
120
- end
121
-
122
- def _update_record(*)
123
- partial_writes? ? super(keys_for_partial_write) : super
124
- end
125
-
126
- def _create_record(*)
127
- partial_writes? ? super(keys_for_partial_write) : super
128
- end
129
-
130
- # Serialized attributes should always be written in case they've been
131
- # changed in place.
132
- def keys_for_partial_write
133
- changed
134
- end
135
-
136
- def _field_changed?(attr, old_value)
137
- @attributes[attr].changed_from?(old_value)
138
- end
196
+ changes_applied
197
+ changes.each { |attr_name, value| _write_attribute(attr_name, value) }
139
198
 
140
- def attributes_changed_in_place
141
- changed_in_place.each_with_object({}) do |attr_name, h|
142
- orig = @attributes[attr_name].original_value
143
- h[attr_name] = orig
199
+ affected_rows
200
+ ensure
201
+ @_touch_attr_names, @_skip_dirty_tracking = nil, nil
144
202
  end
145
- end
146
203
 
147
- def changed_in_place
148
- self.class.attribute_names.select do |attr_name|
149
- attribute_changed_in_place?(attr_name)
204
+ def _update_record(attribute_names = attribute_names_for_partial_writes)
205
+ affected_rows = super
206
+ changes_applied
207
+ affected_rows
150
208
  end
151
- end
152
209
 
153
- def original_raw_attribute(attr_name)
154
- original_raw_attributes.fetch(attr_name) do
155
- read_attribute_before_type_cast(attr_name)
210
+ def _create_record(attribute_names = attribute_names_for_partial_writes)
211
+ id = super
212
+ changes_applied
213
+ id
156
214
  end
157
- end
158
-
159
- def original_raw_attributes
160
- @original_raw_attributes ||= {}
161
- end
162
-
163
- def store_original_raw_attribute(attr_name)
164
- original_raw_attributes[attr_name] = @attributes[attr_name].value_for_database
165
- end
166
215
 
167
- def store_original_raw_attributes
168
- attribute_names.each do |attr|
169
- store_original_raw_attribute(attr)
216
+ def attribute_names_for_partial_writes
217
+ partial_writes? ? changed_attribute_names_to_save : attribute_names
170
218
  end
171
- end
172
-
173
- def cache_changed_attributes
174
- @cached_changed_attributes = changed_attributes
175
- yield
176
- ensure
177
- remove_instance_variable(:@cached_changed_attributes)
178
- end
179
219
  end
180
220
  end
181
221
  end
@@ -1,128 +1,134 @@
1
- require 'set'
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
2
4
 
3
5
  module ActiveRecord
4
6
  module AttributeMethods
5
7
  module PrimaryKey
6
8
  extend ActiveSupport::Concern
7
9
 
8
- # Returns this record's primary key value wrapped in an Array if one is
10
+ # Returns this record's primary key value wrapped in an array if one is
9
11
  # available.
10
12
  def to_key
11
- sync_with_transaction_state
12
- key = self.id
13
+ key = id
13
14
  [key] if key
14
15
  end
15
16
 
16
- # Returns the primary key value.
17
+ # Returns the primary key column's value.
17
18
  def id
18
- if pk = self.class.primary_key
19
- sync_with_transaction_state
20
- _read_attribute(pk)
21
- end
19
+ _read_attribute(@primary_key)
22
20
  end
23
21
 
24
- # Sets the primary key value.
22
+ # Sets the primary key column's value.
25
23
  def id=(value)
26
- sync_with_transaction_state
27
- write_attribute(self.class.primary_key, value) if self.class.primary_key
24
+ _write_attribute(@primary_key, value)
28
25
  end
29
26
 
30
- # Queries the primary key value.
27
+ # Queries the primary key column's value.
31
28
  def id?
32
- sync_with_transaction_state
33
- query_attribute(self.class.primary_key)
29
+ query_attribute(@primary_key)
34
30
  end
35
31
 
36
- # Returns the primary key value before type cast.
32
+ # Returns the primary key column's value before type cast.
37
33
  def id_before_type_cast
38
- sync_with_transaction_state
39
- read_attribute_before_type_cast(self.class.primary_key)
34
+ read_attribute_before_type_cast(@primary_key)
40
35
  end
41
36
 
42
- # Returns the primary key previous value.
37
+ # Returns the primary key column's previous value.
43
38
  def id_was
44
- sync_with_transaction_state
45
- attribute_was(self.class.primary_key)
39
+ attribute_was(@primary_key)
46
40
  end
47
41
 
48
- protected
49
-
50
- def attribute_method?(attr_name)
51
- attr_name == 'id' || super
42
+ # Returns the primary key column's value from the database.
43
+ def id_in_database
44
+ attribute_in_database(@primary_key)
52
45
  end
53
46
 
54
- module ClassMethods
55
- def define_method_attribute(attr_name)
56
- super
57
-
58
- if attr_name == primary_key && attr_name != 'id'
59
- generated_attribute_methods.send(:alias_method, :id, primary_key)
60
- end
47
+ private
48
+ def attribute_method?(attr_name)
49
+ attr_name == "id" || super
61
50
  end
62
51
 
63
- ID_ATTRIBUTE_METHODS = %w(id id= id? id_before_type_cast id_was).to_set
52
+ module ClassMethods
53
+ ID_ATTRIBUTE_METHODS = %w(id id= id? id_before_type_cast id_was id_in_database).to_set
64
54
 
65
- def dangerous_attribute_method?(method_name)
66
- super && !ID_ATTRIBUTE_METHODS.include?(method_name)
67
- end
55
+ def instance_method_already_implemented?(method_name)
56
+ super || primary_key && ID_ATTRIBUTE_METHODS.include?(method_name)
57
+ end
68
58
 
69
- # Defines the primary key field -- can be overridden in subclasses.
70
- # Overwriting will negate any effect of the +primary_key_prefix_type+
71
- # setting, though.
72
- def primary_key
73
- @primary_key = reset_primary_key unless defined? @primary_key
74
- @primary_key
75
- end
59
+ def dangerous_attribute_method?(method_name)
60
+ super && !ID_ATTRIBUTE_METHODS.include?(method_name)
61
+ end
76
62
 
77
- # Returns a quoted version of the primary key name, used to construct
78
- # SQL statements.
79
- def quoted_primary_key
80
- @quoted_primary_key ||= connection.quote_column_name(primary_key)
81
- end
63
+ # Defines the primary key field -- can be overridden in subclasses.
64
+ # Overwriting will negate any effect of the +primary_key_prefix_type+
65
+ # setting, though.
66
+ def primary_key
67
+ @primary_key = reset_primary_key unless defined? @primary_key
68
+ @primary_key
69
+ end
82
70
 
83
- def reset_primary_key #:nodoc:
84
- if self == base_class
85
- self.primary_key = get_primary_key(base_class.name)
86
- else
87
- self.primary_key = base_class.primary_key
71
+ # Returns a quoted version of the primary key name, used to construct
72
+ # SQL statements.
73
+ def quoted_primary_key
74
+ @quoted_primary_key ||= connection.quote_column_name(primary_key)
88
75
  end
89
- end
90
76
 
91
- def get_primary_key(base_name) #:nodoc:
92
- if base_name && primary_key_prefix_type == :table_name
93
- base_name.foreign_key(false)
94
- elsif base_name && primary_key_prefix_type == :table_name_with_underscore
95
- base_name.foreign_key
96
- else
97
- if ActiveRecord::Base != self && table_exists?
98
- connection.schema_cache.primary_keys(table_name)
77
+ def reset_primary_key #:nodoc:
78
+ if base_class?
79
+ self.primary_key = get_primary_key(base_class.name)
99
80
  else
100
- 'id'
81
+ self.primary_key = base_class.primary_key
82
+ end
83
+ end
84
+
85
+ def get_primary_key(base_name) #:nodoc:
86
+ if base_name && primary_key_prefix_type == :table_name
87
+ base_name.foreign_key(false)
88
+ elsif base_name && primary_key_prefix_type == :table_name_with_underscore
89
+ base_name.foreign_key
90
+ else
91
+ if ActiveRecord::Base != self && table_exists?
92
+ pk = connection.schema_cache.primary_keys(table_name)
93
+ suppress_composite_primary_key(pk)
94
+ else
95
+ "id"
96
+ end
101
97
  end
102
98
  end
103
- end
104
99
 
105
- # Sets the name of the primary key column.
106
- #
107
- # class Project < ActiveRecord::Base
108
- # self.primary_key = 'sysid'
109
- # end
110
- #
111
- # You can also define the +primary_key+ method yourself:
112
- #
113
- # class Project < ActiveRecord::Base
114
- # def self.primary_key
115
- # 'foo_' + super
116
- # end
117
- # end
118
- #
119
- # Project.primary_key # => "foo_id"
120
- def primary_key=(value)
121
- @primary_key = value && value.to_s
122
- @quoted_primary_key = nil
123
- @attributes_builder = nil
100
+ # Sets the name of the primary key column.
101
+ #
102
+ # class Project < ActiveRecord::Base
103
+ # self.primary_key = 'sysid'
104
+ # end
105
+ #
106
+ # You can also define the #primary_key method yourself:
107
+ #
108
+ # class Project < ActiveRecord::Base
109
+ # def self.primary_key
110
+ # 'foo_' + super
111
+ # end
112
+ # end
113
+ #
114
+ # Project.primary_key # => "foo_id"
115
+ def primary_key=(value)
116
+ @primary_key = value && -value.to_s
117
+ @quoted_primary_key = nil
118
+ @attributes_builder = nil
119
+ end
120
+
121
+ private
122
+ def suppress_composite_primary_key(pk)
123
+ return pk unless pk.is_a?(Array)
124
+
125
+ warn <<~WARNING
126
+ WARNING: Active Record does not support composite primary key.
127
+
128
+ #{table_name} has composite primary key. Composite primary key is ignored.
129
+ WARNING
130
+ end
124
131
  end
125
- end
126
132
  end
127
133
  end
128
134
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module AttributeMethods
3
5
  module Query
@@ -14,15 +16,14 @@ module ActiveRecord
14
16
  when true then true
15
17
  when false, nil then false
16
18
  else
17
- column = self.class.columns_hash[attr_name]
18
- if column.nil?
19
+ if !type_for_attribute(attr_name) { false }
19
20
  if Numeric === value || value !~ /[^0-9]/
20
21
  !value.to_i.zero?
21
22
  else
22
- return false if ActiveRecord::ConnectionAdapters::Column::FALSE_VALUES.include?(value)
23
+ return false if ActiveModel::Type::Boolean::FALSE_VALUES.include?(value)
23
24
  !value.blank?
24
25
  end
25
- elsif column.number?
26
+ elsif value.respond_to?(:zero?)
26
27
  !value.zero?
27
28
  else
28
29
  !value.blank?
@@ -31,7 +32,7 @@ module ActiveRecord
31
32
  end
32
33
 
33
34
  private
34
- # Handle *? for method_missing.
35
+ # Dispatch target for <tt>*?</tt> attribute methods.
35
36
  def attribute?(attribute_name)
36
37
  query_attribute(attribute_name)
37
38
  end