activerecord 4.2.0 → 6.1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (374) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1221 -796
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +15 -14
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/aggregations.rb +267 -249
  8. data/lib/active_record/association_relation.rb +45 -7
  9. data/lib/active_record/associations/alias_tracker.rb +40 -43
  10. data/lib/active_record/associations/association.rb +172 -67
  11. data/lib/active_record/associations/association_scope.rb +105 -129
  12. data/lib/active_record/associations/belongs_to_association.rb +85 -59
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
  14. data/lib/active_record/associations/builder/association.rb +57 -43
  15. data/lib/active_record/associations/builder/belongs_to.rb +74 -57
  16. data/lib/active_record/associations/builder/collection_association.rb +15 -33
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +57 -70
  18. data/lib/active_record/associations/builder/has_many.rb +13 -5
  19. data/lib/active_record/associations/builder/has_one.rb +44 -6
  20. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  21. data/lib/active_record/associations/collection_association.rb +168 -279
  22. data/lib/active_record/associations/collection_proxy.rb +263 -155
  23. data/lib/active_record/associations/foreign_association.rb +33 -0
  24. data/lib/active_record/associations/has_many_association.rb +57 -84
  25. data/lib/active_record/associations/has_many_through_association.rb +70 -82
  26. data/lib/active_record/associations/has_one_association.rb +74 -47
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +54 -73
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  31. data/lib/active_record/associations/join_dependency.rb +175 -164
  32. data/lib/active_record/associations/preloader/association.rb +107 -112
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +99 -96
  35. data/lib/active_record/associations/singular_association.rb +18 -45
  36. data/lib/active_record/associations/through_association.rb +49 -24
  37. data/lib/active_record/associations.rb +1845 -1597
  38. data/lib/active_record/attribute_assignment.rb +59 -185
  39. data/lib/active_record/attribute_methods/before_type_cast.rb +20 -7
  40. data/lib/active_record/attribute_methods/dirty.rb +168 -138
  41. data/lib/active_record/attribute_methods/primary_key.rb +93 -83
  42. data/lib/active_record/attribute_methods/query.rb +8 -10
  43. data/lib/active_record/attribute_methods/read.rb +19 -79
  44. data/lib/active_record/attribute_methods/serialization.rb +49 -24
  45. data/lib/active_record/attribute_methods/time_zone_conversion.rb +59 -36
  46. data/lib/active_record/attribute_methods/write.rb +25 -56
  47. data/lib/active_record/attribute_methods.rb +153 -162
  48. data/lib/active_record/attributes.rb +234 -70
  49. data/lib/active_record/autosave_association.rb +157 -69
  50. data/lib/active_record/base.rb +49 -50
  51. data/lib/active_record/callbacks.rb +234 -79
  52. data/lib/active_record/coders/json.rb +3 -1
  53. data/lib/active_record/coders/yaml_column.rb +46 -13
  54. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +887 -317
  55. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -41
  56. data/lib/active_record/connection_adapters/abstract/database_statements.rb +301 -113
  57. data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -24
  58. data/lib/active_record/connection_adapters/abstract/quoting.rb +187 -60
  59. data/lib/active_record/connection_adapters/abstract/savepoints.rb +9 -7
  60. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +157 -93
  61. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +485 -253
  62. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  63. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +909 -263
  64. data/lib/active_record/connection_adapters/abstract/transaction.rb +254 -92
  65. data/lib/active_record/connection_adapters/abstract_adapter.rb +492 -221
  66. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +580 -608
  67. data/lib/active_record/connection_adapters/column.rb +67 -40
  68. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  69. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  70. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  71. data/lib/active_record/connection_adapters/mysql/database_statements.rb +196 -0
  72. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  73. data/lib/active_record/connection_adapters/mysql/quoting.rb +96 -0
  74. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +97 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +103 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +91 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +271 -0
  78. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
  79. data/lib/active_record/connection_adapters/mysql2_adapter.rb +81 -199
  80. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  81. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +44 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +78 -161
  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 +8 -6
  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/interval.rb +49 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  98. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  101. data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +70 -34
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +67 -51
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  109. data/lib/active_record/connection_adapters/postgresql/oid.rb +25 -25
  110. data/lib/active_record/connection_adapters/postgresql/quoting.rb +171 -48
  111. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  112. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  114. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
  115. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +499 -293
  116. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +44 -0
  117. data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
  118. data/lib/active_record/connection_adapters/postgresql_adapter.rb +595 -382
  119. data/lib/active_record/connection_adapters/schema_cache.rb +191 -29
  120. data/lib/active_record/connection_adapters/sql_type_metadata.rb +45 -0
  121. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +146 -0
  122. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  123. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +21 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  126. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  127. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
  128. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +322 -389
  129. data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
  130. data/lib/active_record/connection_adapters.rb +52 -0
  131. data/lib/active_record/connection_handling.rb +314 -41
  132. data/lib/active_record/core.rb +488 -243
  133. data/lib/active_record/counter_cache.rb +71 -50
  134. data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -0
  135. data/lib/active_record/database_configurations/database_config.rb +80 -0
  136. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  137. data/lib/active_record/database_configurations/url_config.rb +53 -0
  138. data/lib/active_record/database_configurations.rb +273 -0
  139. data/lib/active_record/delegated_type.rb +209 -0
  140. data/lib/active_record/destroy_association_async_job.rb +36 -0
  141. data/lib/active_record/dynamic_matchers.rb +87 -106
  142. data/lib/active_record/enum.rb +212 -94
  143. data/lib/active_record/errors.rb +225 -54
  144. data/lib/active_record/explain.rb +27 -11
  145. data/lib/active_record/explain_registry.rb +4 -2
  146. data/lib/active_record/explain_subscriber.rb +11 -6
  147. data/lib/active_record/fixture_set/file.rb +33 -14
  148. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  149. data/lib/active_record/fixture_set/render_context.rb +17 -0
  150. data/lib/active_record/fixture_set/table_row.rb +152 -0
  151. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  152. data/lib/active_record/fixtures.rb +273 -496
  153. data/lib/active_record/gem_version.rb +6 -4
  154. data/lib/active_record/inheritance.rb +175 -110
  155. data/lib/active_record/insert_all.rb +212 -0
  156. data/lib/active_record/integration.rb +121 -29
  157. data/lib/active_record/internal_metadata.rb +64 -0
  158. data/lib/active_record/legacy_yaml_adapter.rb +52 -0
  159. data/lib/active_record/locale/en.yml +3 -2
  160. data/lib/active_record/locking/optimistic.rb +103 -95
  161. data/lib/active_record/locking/pessimistic.rb +22 -6
  162. data/lib/active_record/log_subscriber.rb +93 -31
  163. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  164. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  165. data/lib/active_record/middleware/database_selector.rb +77 -0
  166. data/lib/active_record/migration/command_recorder.rb +185 -90
  167. data/lib/active_record/migration/compatibility.rb +298 -0
  168. data/lib/active_record/migration/join_table.rb +8 -7
  169. data/lib/active_record/migration.rb +685 -309
  170. data/lib/active_record/model_schema.rb +420 -113
  171. data/lib/active_record/nested_attributes.rb +265 -216
  172. data/lib/active_record/no_touching.rb +15 -2
  173. data/lib/active_record/null_relation.rb +24 -38
  174. data/lib/active_record/persistence.rb +574 -135
  175. data/lib/active_record/query_cache.rb +29 -23
  176. data/lib/active_record/querying.rb +50 -31
  177. data/lib/active_record/railtie.rb +175 -54
  178. data/lib/active_record/railties/console_sandbox.rb +3 -3
  179. data/lib/active_record/railties/controller_runtime.rb +34 -33
  180. data/lib/active_record/railties/databases.rake +533 -216
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +485 -310
  183. data/lib/active_record/relation/batches/batch_enumerator.rb +85 -0
  184. data/lib/active_record/relation/batches.rb +217 -59
  185. data/lib/active_record/relation/calculations.rb +326 -244
  186. data/lib/active_record/relation/delegation.rb +76 -84
  187. data/lib/active_record/relation/finder_methods.rb +318 -256
  188. data/lib/active_record/relation/from_clause.rb +30 -0
  189. data/lib/active_record/relation/merger.rb +99 -84
  190. data/lib/active_record/relation/predicate_builder/array_handler.rb +26 -25
  191. data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
  192. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  193. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +57 -0
  194. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  195. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  196. data/lib/active_record/relation/predicate_builder.rb +139 -96
  197. data/lib/active_record/relation/query_attribute.rb +50 -0
  198. data/lib/active_record/relation/query_methods.rb +757 -409
  199. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  200. data/lib/active_record/relation/spawn_methods.rb +23 -21
  201. data/lib/active_record/relation/where_clause.rb +239 -0
  202. data/lib/active_record/relation.rb +554 -342
  203. data/lib/active_record/result.rb +91 -47
  204. data/lib/active_record/runtime_registry.rb +6 -4
  205. data/lib/active_record/sanitization.rb +134 -122
  206. data/lib/active_record/schema.rb +21 -24
  207. data/lib/active_record/schema_dumper.rb +141 -92
  208. data/lib/active_record/schema_migration.rb +24 -26
  209. data/lib/active_record/scoping/default.rb +96 -82
  210. data/lib/active_record/scoping/named.rb +78 -36
  211. data/lib/active_record/scoping.rb +45 -27
  212. data/lib/active_record/secure_token.rb +48 -0
  213. data/lib/active_record/serialization.rb +8 -6
  214. data/lib/active_record/signed_id.rb +116 -0
  215. data/lib/active_record/statement_cache.rb +89 -36
  216. data/lib/active_record/store.rb +133 -43
  217. data/lib/active_record/suppressor.rb +61 -0
  218. data/lib/active_record/table_metadata.rb +81 -0
  219. data/lib/active_record/tasks/database_tasks.rb +366 -129
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +68 -100
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +87 -39
  222. data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -19
  223. data/lib/active_record/test_databases.rb +24 -0
  224. data/lib/active_record/test_fixtures.rb +291 -0
  225. data/lib/active_record/timestamp.rb +86 -43
  226. data/lib/active_record/touch_later.rb +65 -0
  227. data/lib/active_record/transactions.rb +181 -152
  228. data/lib/active_record/translation.rb +3 -1
  229. data/lib/active_record/type/adapter_specific_registry.rb +126 -0
  230. data/lib/active_record/type/date.rb +4 -41
  231. data/lib/active_record/type/date_time.rb +4 -38
  232. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  233. data/lib/active_record/type/hash_lookup_type_map.rb +12 -5
  234. data/lib/active_record/type/internal/timezone.rb +17 -0
  235. data/lib/active_record/type/json.rb +30 -0
  236. data/lib/active_record/type/serialized.rb +33 -15
  237. data/lib/active_record/type/text.rb +2 -2
  238. data/lib/active_record/type/time.rb +21 -16
  239. data/lib/active_record/type/type_map.rb +16 -19
  240. data/lib/active_record/type/unsigned_integer.rb +9 -8
  241. data/lib/active_record/type.rb +84 -23
  242. data/lib/active_record/type_caster/connection.rb +33 -0
  243. data/lib/active_record/type_caster/map.rb +23 -0
  244. data/lib/active_record/type_caster.rb +9 -0
  245. data/lib/active_record/validations/absence.rb +25 -0
  246. data/lib/active_record/validations/associated.rb +12 -4
  247. data/lib/active_record/validations/length.rb +26 -0
  248. data/lib/active_record/validations/numericality.rb +35 -0
  249. data/lib/active_record/validations/presence.rb +14 -13
  250. data/lib/active_record/validations/uniqueness.rb +65 -48
  251. data/lib/active_record/validations.rb +39 -35
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/active_record.rb +44 -28
  254. data/lib/arel/alias_predication.rb +9 -0
  255. data/lib/arel/attributes/attribute.rb +41 -0
  256. data/lib/arel/collectors/bind.rb +29 -0
  257. data/lib/arel/collectors/composite.rb +39 -0
  258. data/lib/arel/collectors/plain_string.rb +20 -0
  259. data/lib/arel/collectors/sql_string.rb +27 -0
  260. data/lib/arel/collectors/substitute_binds.rb +35 -0
  261. data/lib/arel/crud.rb +42 -0
  262. data/lib/arel/delete_manager.rb +18 -0
  263. data/lib/arel/errors.rb +9 -0
  264. data/lib/arel/expressions.rb +29 -0
  265. data/lib/arel/factory_methods.rb +49 -0
  266. data/lib/arel/insert_manager.rb +49 -0
  267. data/lib/arel/math.rb +45 -0
  268. data/lib/arel/nodes/and.rb +32 -0
  269. data/lib/arel/nodes/ascending.rb +23 -0
  270. data/lib/arel/nodes/binary.rb +126 -0
  271. data/lib/arel/nodes/bind_param.rb +44 -0
  272. data/lib/arel/nodes/case.rb +55 -0
  273. data/lib/arel/nodes/casted.rb +62 -0
  274. data/lib/arel/nodes/comment.rb +29 -0
  275. data/lib/arel/nodes/count.rb +12 -0
  276. data/lib/arel/nodes/delete_statement.rb +45 -0
  277. data/lib/arel/nodes/descending.rb +23 -0
  278. data/lib/arel/nodes/equality.rb +15 -0
  279. data/lib/arel/nodes/extract.rb +24 -0
  280. data/lib/arel/nodes/false.rb +16 -0
  281. data/lib/arel/nodes/full_outer_join.rb +8 -0
  282. data/lib/arel/nodes/function.rb +44 -0
  283. data/lib/arel/nodes/grouping.rb +11 -0
  284. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  285. data/lib/arel/nodes/in.rb +15 -0
  286. data/lib/arel/nodes/infix_operation.rb +92 -0
  287. data/lib/arel/nodes/inner_join.rb +8 -0
  288. data/lib/arel/nodes/insert_statement.rb +37 -0
  289. data/lib/arel/nodes/join_source.rb +20 -0
  290. data/lib/arel/nodes/matches.rb +18 -0
  291. data/lib/arel/nodes/named_function.rb +23 -0
  292. data/lib/arel/nodes/node.rb +51 -0
  293. data/lib/arel/nodes/node_expression.rb +13 -0
  294. data/lib/arel/nodes/ordering.rb +27 -0
  295. data/lib/arel/nodes/outer_join.rb +8 -0
  296. data/lib/arel/nodes/over.rb +15 -0
  297. data/lib/arel/nodes/regexp.rb +16 -0
  298. data/lib/arel/nodes/right_outer_join.rb +8 -0
  299. data/lib/arel/nodes/select_core.rb +67 -0
  300. data/lib/arel/nodes/select_statement.rb +41 -0
  301. data/lib/arel/nodes/sql_literal.rb +19 -0
  302. data/lib/arel/nodes/string_join.rb +11 -0
  303. data/lib/arel/nodes/table_alias.rb +31 -0
  304. data/lib/arel/nodes/terminal.rb +16 -0
  305. data/lib/arel/nodes/true.rb +16 -0
  306. data/lib/arel/nodes/unary.rb +44 -0
  307. data/lib/arel/nodes/unary_operation.rb +20 -0
  308. data/lib/arel/nodes/unqualified_column.rb +22 -0
  309. data/lib/arel/nodes/update_statement.rb +41 -0
  310. data/lib/arel/nodes/values_list.rb +9 -0
  311. data/lib/arel/nodes/window.rb +126 -0
  312. data/lib/arel/nodes/with.rb +11 -0
  313. data/lib/arel/nodes.rb +70 -0
  314. data/lib/arel/order_predications.rb +13 -0
  315. data/lib/arel/predications.rb +250 -0
  316. data/lib/arel/select_manager.rb +270 -0
  317. data/lib/arel/table.rb +118 -0
  318. data/lib/arel/tree_manager.rb +72 -0
  319. data/lib/arel/update_manager.rb +34 -0
  320. data/lib/arel/visitors/dot.rb +308 -0
  321. data/lib/arel/visitors/mysql.rb +93 -0
  322. data/lib/arel/visitors/postgresql.rb +120 -0
  323. data/lib/arel/visitors/sqlite.rb +38 -0
  324. data/lib/arel/visitors/to_sql.rb +899 -0
  325. data/lib/arel/visitors/visitor.rb +45 -0
  326. data/lib/arel/visitors.rb +13 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +54 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  330. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +43 -37
  332. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +26 -0
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +13 -10
  334. data/lib/rails/generators/active_record/migration.rb +35 -1
  335. data/lib/rails/generators/active_record/model/model_generator.rb +55 -22
  336. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  337. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  338. data/lib/rails/generators/active_record.rb +7 -5
  339. metadata +175 -65
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  342. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  343. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  344. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  347. data/lib/active_record/attribute.rb +0 -149
  348. data/lib/active_record/attribute_decorators.rb +0 -66
  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/connection_specification.rb +0 -275
  352. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  353. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  354. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  355. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  356. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  357. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  358. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  359. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  360. data/lib/active_record/type/big_integer.rb +0 -13
  361. data/lib/active_record/type/binary.rb +0 -50
  362. data/lib/active_record/type/boolean.rb +0 -30
  363. data/lib/active_record/type/decimal.rb +0 -40
  364. data/lib/active_record/type/decorator.rb +0 -14
  365. data/lib/active_record/type/float.rb +0 -19
  366. data/lib/active_record/type/integer.rb +0 -55
  367. data/lib/active_record/type/mutable.rb +0 -16
  368. data/lib/active_record/type/numeric.rb +0 -36
  369. data/lib/active_record/type/string.rb +0 -36
  370. data/lib/active_record/type/time_value.rb +0 -38
  371. data/lib/active_record/type/value.rb +0 -101
  372. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
  373. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
  374. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -1,7 +1,7 @@
1
- require 'active_support/core_ext/enumerable'
2
- require 'active_support/core_ext/string/filters'
3
- require 'mutex_m'
4
- require 'thread_safe'
1
+ # frozen_string_literal: true
2
+
3
+ require "mutex_m"
4
+ require "active_support/core_ext/enumerable"
5
5
 
6
6
  module ActiveRecord
7
7
  # = Active Record Attribute Methods
@@ -19,47 +19,25 @@ module ActiveRecord
19
19
  include TimeZoneConversion
20
20
  include Dirty
21
21
  include Serialization
22
-
23
- delegate :column_for_attribute, to: :class
24
22
  end
25
23
 
26
- AttrNames = Module.new {
27
- def self.set_name_cache(name, value)
28
- const_name = "ATTR_#{name}"
29
- unless const_defined? const_name
30
- const_set const_name, value.dup.freeze
31
- end
32
- end
33
- }
34
-
35
- BLACKLISTED_CLASS_METHODS = %w(private public protected allocate new name parent superclass)
36
-
37
- class AttributeMethodCache
38
- def initialize
39
- @module = Module.new
40
- @method_cache = ThreadSafe::Cache.new
41
- end
24
+ RESTRICTED_CLASS_METHODS = %w(private public protected allocate new name parent superclass)
42
25
 
43
- def [](name)
44
- @method_cache.compute_if_absent(name) do
45
- safe_name = name.unpack('h*').first
46
- temp_method = "__temp__#{safe_name}"
47
- ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
48
- @module.module_eval method_body(temp_method, safe_name), __FILE__, __LINE__
49
- @module.instance_method temp_method
50
- end
51
- end
52
-
53
- private
26
+ class GeneratedAttributeMethods < Module #:nodoc:
27
+ include Mutex_m
28
+ end
54
29
 
55
- # Override this method in the subclasses for method body.
56
- def method_body(method_name, const_name)
57
- raise NotImplementedError, "Subclasses must implement a method_body(method_name, const_name) method."
30
+ class << self
31
+ def dangerous_attribute_methods # :nodoc:
32
+ @dangerous_attribute_methods ||= (
33
+ Base.instance_methods +
34
+ Base.private_instance_methods -
35
+ Base.superclass.instance_methods -
36
+ Base.superclass.private_instance_methods
37
+ ).map { |m| -m.to_s }.to_set.freeze
58
38
  end
59
39
  end
60
40
 
61
- class GeneratedAttributeMethods < Module; end # :nodoc:
62
-
63
41
  module ClassMethods
64
42
  def inherited(child_class) #:nodoc:
65
43
  child_class.initialize_generated_modules
@@ -67,7 +45,8 @@ module ActiveRecord
67
45
  end
68
46
 
69
47
  def initialize_generated_modules # :nodoc:
70
- @generated_attribute_methods = GeneratedAttributeMethods.new { extend Mutex_m }
48
+ @generated_attribute_methods = const_set(:GeneratedAttributeMethods, GeneratedAttributeMethods.new)
49
+ private_constant :GeneratedAttributeMethods
71
50
  @attribute_methods_generated = false
72
51
  include @generated_attribute_methods
73
52
 
@@ -82,11 +61,10 @@ module ActiveRecord
82
61
  # attribute methods.
83
62
  generated_attribute_methods.synchronize do
84
63
  return false if @attribute_methods_generated
85
- superclass.define_attribute_methods unless self == base_class
86
- super(column_names)
64
+ superclass.define_attribute_methods unless base_class?
65
+ super(attribute_names)
87
66
  @attribute_methods_generated = true
88
67
  end
89
- true
90
68
  end
91
69
 
92
70
  def undefine_attribute_methods # :nodoc:
@@ -96,7 +74,7 @@ module ActiveRecord
96
74
  end
97
75
  end
98
76
 
99
- # Raises a <tt>ActiveRecord::DangerousAttributeError</tt> exception when an
77
+ # Raises an ActiveRecord::DangerousAttributeError exception when an
100
78
  # \Active \Record method is defined in the model, otherwise +false+.
101
79
  #
102
80
  # class Person < ActiveRecord::Base
@@ -106,7 +84,7 @@ module ActiveRecord
106
84
  # end
107
85
  #
108
86
  # Person.instance_method_already_implemented?(:save)
109
- # # => ActiveRecord::DangerousAttributeError: save is defined by ActiveRecord
87
+ # # => ActiveRecord::DangerousAttributeError: save is defined by Active Record. Check to make sure that you don't have an attribute or method with the same name.
110
88
  #
111
89
  # Person.instance_method_already_implemented?(:name)
112
90
  # # => false
@@ -129,7 +107,7 @@ module ActiveRecord
129
107
  # A method name is 'dangerous' if it is already (re)defined by Active Record, but
130
108
  # not by any ancestors. (So 'puts' is not dangerous but 'save' is.)
131
109
  def dangerous_attribute_method?(name) # :nodoc:
132
- method_defined_within?(name, Base)
110
+ ::ActiveRecord::AttributeMethods.dangerous_attribute_methods.include?(name.to_s)
133
111
  end
134
112
 
135
113
  def method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc:
@@ -147,13 +125,11 @@ module ActiveRecord
147
125
  # A class method is 'dangerous' if it is already (re)defined by Active Record, but
148
126
  # not by any ancestors. (So 'puts' is not dangerous but 'new' is.)
149
127
  def dangerous_class_method?(method_name)
150
- BLACKLISTED_CLASS_METHODS.include?(method_name.to_s) || class_method_defined_within?(method_name, Base)
151
- end
128
+ return true if RESTRICTED_CLASS_METHODS.include?(method_name.to_s)
152
129
 
153
- def class_method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc
154
- if klass.respond_to?(name, true)
155
- if superklass.respond_to?(name, true)
156
- klass.method(name).owner != superklass.method(name).owner
130
+ if Base.respond_to?(method_name, true)
131
+ if Object.respond_to?(method_name, true)
132
+ Base.method(method_name).owner != Object.method(method_name).owner
157
133
  else
158
134
  true
159
135
  end
@@ -172,7 +148,7 @@ module ActiveRecord
172
148
  # Person.attribute_method?(:age=) # => true
173
149
  # Person.attribute_method?(:nothing) # => false
174
150
  def attribute_method?(attribute)
175
- super || (table_exists? && column_names.include?(attribute.to_s.sub(/=$/, '')))
151
+ super || (table_exists? && column_names.include?(attribute.to_s.delete_suffix("=")))
176
152
  end
177
153
 
178
154
  # Returns an array of column names as strings if it's not an abstract class and
@@ -185,79 +161,84 @@ module ActiveRecord
185
161
  # # => ["id", "created_at", "updated_at", "name", "age"]
186
162
  def attribute_names
187
163
  @attribute_names ||= if !abstract_class? && table_exists?
188
- column_names
189
- else
190
- []
191
- end
164
+ attribute_types.keys
165
+ else
166
+ []
167
+ end.freeze
192
168
  end
193
169
 
194
- # Returns the column object for the named attribute.
195
- # Returns nil if the named attribute does not exist.
170
+ # Returns true if the given attribute exists, otherwise false.
196
171
  #
197
172
  # class Person < ActiveRecord::Base
173
+ # alias_attribute :new_name, :name
198
174
  # end
199
175
  #
200
- # person = Person.new
201
- # person.column_for_attribute(:name) # the result depends on the ConnectionAdapter
202
- # # => #<ActiveRecord::ConnectionAdapters::Column:0x007ff4ab083980 @name="name", @sql_type="varchar(255)", @null=true, ...>
203
- #
204
- # person.column_for_attribute(:nothing)
205
- # # => nil
206
- def column_for_attribute(name)
207
- column = columns_hash[name.to_s]
208
- if column.nil?
209
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
210
- `#column_for_attribute` will return a null object for non-existent
211
- columns in Rails 5. Use `#has_attribute?` if you need to check for
212
- an attribute's existence.
213
- MSG
214
- end
215
- column
176
+ # Person.has_attribute?('name') # => true
177
+ # Person.has_attribute?('new_name') # => true
178
+ # Person.has_attribute?(:age) # => true
179
+ # Person.has_attribute?(:nothing) # => false
180
+ def has_attribute?(attr_name)
181
+ attr_name = attr_name.to_s
182
+ attr_name = attribute_aliases[attr_name] || attr_name
183
+ attribute_types.key?(attr_name)
184
+ end
185
+
186
+ def _has_attribute?(attr_name) # :nodoc:
187
+ attribute_types.key?(attr_name)
216
188
  end
217
189
  end
218
190
 
219
191
  # A Person object with a name attribute can ask <tt>person.respond_to?(:name)</tt>,
220
192
  # <tt>person.respond_to?(:name=)</tt>, and <tt>person.respond_to?(:name?)</tt>
221
- # which will all return +true+. It also define the attribute methods if they have
193
+ # which will all return +true+. It also defines the attribute methods if they have
222
194
  # not been generated.
223
195
  #
224
196
  # class Person < ActiveRecord::Base
225
197
  # end
226
198
  #
227
199
  # person = Person.new
228
- # person.respond_to(:name) # => true
229
- # person.respond_to(:name=) # => true
230
- # person.respond_to(:name?) # => true
231
- # person.respond_to('age') # => true
232
- # person.respond_to('age=') # => true
233
- # person.respond_to('age?') # => true
234
- # person.respond_to(:nothing) # => false
200
+ # person.respond_to?(:name) # => true
201
+ # person.respond_to?(:name=) # => true
202
+ # person.respond_to?(:name?) # => true
203
+ # person.respond_to?('age') # => true
204
+ # person.respond_to?('age=') # => true
205
+ # person.respond_to?('age?') # => true
206
+ # person.respond_to?(:nothing) # => false
235
207
  def respond_to?(name, include_private = false)
236
208
  return false unless super
237
- name = name.to_s
238
209
 
239
210
  # If the result is true then check for the select case.
240
211
  # For queries selecting a subset of columns, return false for unselected columns.
241
212
  # We check defined?(@attributes) not to issue warnings if called on objects that
242
213
  # have been allocated but not yet initialized.
243
- if defined?(@attributes) && self.class.column_names.include?(name)
244
- return has_attribute?(name)
214
+ if defined?(@attributes)
215
+ if name = self.class.symbol_column_to_string(name.to_sym)
216
+ return _has_attribute?(name)
217
+ end
245
218
  end
246
219
 
247
- return true
220
+ true
248
221
  end
249
222
 
250
223
  # Returns +true+ if the given attribute is in the attributes hash, otherwise +false+.
251
224
  #
252
225
  # class Person < ActiveRecord::Base
226
+ # alias_attribute :new_name, :name
253
227
  # end
254
228
  #
255
229
  # person = Person.new
256
- # person.has_attribute?(:name) # => true
257
- # person.has_attribute?('age') # => true
258
- # person.has_attribute?(:nothing) # => false
230
+ # person.has_attribute?(:name) # => true
231
+ # person.has_attribute?(:new_name) # => true
232
+ # person.has_attribute?('age') # => true
233
+ # person.has_attribute?(:nothing) # => false
259
234
  def has_attribute?(attr_name)
260
- @attributes.key?(attr_name.to_s)
235
+ attr_name = attr_name.to_s
236
+ attr_name = self.class.attribute_aliases[attr_name] || attr_name
237
+ @attributes.key?(attr_name)
238
+ end
239
+
240
+ def _has_attribute?(attr_name) # :nodoc:
241
+ @attributes.key?(attr_name)
261
242
  end
262
243
 
263
244
  # Returns an array of names for the attributes available on this object.
@@ -287,9 +268,8 @@ module ActiveRecord
287
268
  # Returns an <tt>#inspect</tt>-like string for the value of the
288
269
  # attribute +attr_name+. String attributes are truncated up to 50
289
270
  # characters, Date and Time attributes are returned in the
290
- # <tt>:db</tt> format, Array attributes are truncated up to 10 values.
291
- # Other attributes return the value of <tt>#inspect</tt> without
292
- # modification.
271
+ # <tt>:db</tt> format. Other attributes return the value of
272
+ # <tt>#inspect</tt> without modification.
293
273
  #
294
274
  # person = Person.create!(name: 'David Heinemeier Hansson ' * 3)
295
275
  #
@@ -300,20 +280,12 @@ module ActiveRecord
300
280
  # # => "\"2012-10-22 00:15:07\""
301
281
  #
302
282
  # person.attribute_for_inspect(:tag_ids)
303
- # # => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...]"
283
+ # # => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]"
304
284
  def attribute_for_inspect(attr_name)
305
- value = read_attribute(attr_name)
306
-
307
- if value.is_a?(String) && value.length > 50
308
- "#{value[0, 50]}...".inspect
309
- elsif value.is_a?(Date) || value.is_a?(Time)
310
- %("#{value.to_s(:db)}")
311
- elsif value.is_a?(Array) && value.size > 10
312
- inspected = value.first(10).inspect
313
- %(#{inspected[0...-1]}, ...])
314
- else
315
- value.inspect
316
- end
285
+ attr_name = attr_name.to_s
286
+ attr_name = self.class.attribute_aliases[attr_name] || attr_name
287
+ value = _read_attribute(attr_name)
288
+ format_for_inspect(attr_name, value)
317
289
  end
318
290
 
319
291
  # Returns +true+ if the specified +attribute+ has been set by the user or by a
@@ -331,8 +303,10 @@ module ActiveRecord
331
303
  # task.is_done = true
332
304
  # task.attribute_present?(:title) # => true
333
305
  # task.attribute_present?(:is_done) # => true
334
- def attribute_present?(attribute)
335
- value = _read_attribute(attribute)
306
+ def attribute_present?(attr_name)
307
+ attr_name = attr_name.to_s
308
+ attr_name = self.class.attribute_aliases[attr_name] || attr_name
309
+ value = _read_attribute(attr_name)
336
310
  !value.nil? && !(value.respond_to?(:empty?) && value.empty?)
337
311
  end
338
312
 
@@ -342,8 +316,6 @@ module ActiveRecord
342
316
  #
343
317
  # Note: +:id+ is always present.
344
318
  #
345
- # Alias for the <tt>read_attribute</tt> method.
346
- #
347
319
  # class Person < ActiveRecord::Base
348
320
  # belongs_to :organization
349
321
  # end
@@ -360,7 +332,7 @@ module ActiveRecord
360
332
  end
361
333
 
362
334
  # Updates the attribute identified by <tt>attr_name</tt> with the specified +value+.
363
- # (Alias for the protected <tt>write_attribute</tt> method).
335
+ # (Alias for the protected #write_attribute method).
364
336
  #
365
337
  # class Person < ActiveRecord::Base
366
338
  # end
@@ -368,72 +340,91 @@ module ActiveRecord
368
340
  # person = Person.new
369
341
  # person[:age] = '22'
370
342
  # person[:age] # => 22
371
- # person[:age] # => Fixnum
343
+ # person[:age].class # => Integer
372
344
  def []=(attr_name, value)
373
345
  write_attribute(attr_name, value)
374
346
  end
375
347
 
376
- protected
377
-
378
- def clone_attribute_value(reader_method, attribute_name) # :nodoc:
379
- value = send(reader_method, attribute_name)
380
- value.duplicable? ? value.clone : value
381
- rescue TypeError, NoMethodError
382
- value
383
- end
384
-
385
- def arel_attributes_with_values_for_create(attribute_names) # :nodoc:
386
- arel_attributes_with_values(attributes_for_create(attribute_names))
387
- end
388
-
389
- def arel_attributes_with_values_for_update(attribute_names) # :nodoc:
390
- arel_attributes_with_values(attributes_for_update(attribute_names))
391
- end
392
-
393
- def attribute_method?(attr_name) # :nodoc:
394
- # We check defined? because Syck calls respond_to? before actually calling initialize.
395
- defined?(@attributes) && @attributes.key?(attr_name)
348
+ # Returns the name of all database fields which have been read from this
349
+ # model. This can be useful in development mode to determine which fields
350
+ # need to be selected. For performance critical pages, selecting only the
351
+ # required fields can be an easy performance win (assuming you aren't using
352
+ # all of the fields on the model).
353
+ #
354
+ # For example:
355
+ #
356
+ # class PostsController < ActionController::Base
357
+ # after_action :print_accessed_fields, only: :index
358
+ #
359
+ # def index
360
+ # @posts = Post.all
361
+ # end
362
+ #
363
+ # private
364
+ #
365
+ # def print_accessed_fields
366
+ # p @posts.first.accessed_fields
367
+ # end
368
+ # end
369
+ #
370
+ # Which allows you to quickly change your code to:
371
+ #
372
+ # class PostsController < ActionController::Base
373
+ # def index
374
+ # @posts = Post.select(:id, :title, :author_id, :updated_at)
375
+ # end
376
+ # end
377
+ def accessed_fields
378
+ @attributes.accessed
396
379
  end
397
380
 
398
381
  private
382
+ def attribute_method?(attr_name)
383
+ # We check defined? because Syck calls respond_to? before actually calling initialize.
384
+ defined?(@attributes) && @attributes.key?(attr_name)
385
+ end
399
386
 
400
- # Returns a Hash of the Arel::Attributes and attribute values that have been
401
- # typecasted for use in an Arel insert/update method.
402
- def arel_attributes_with_values(attribute_names)
403
- attrs = {}
404
- arel_table = self.class.arel_table
405
-
406
- attribute_names.each do |name|
407
- attrs[arel_table[name]] = typecasted_attribute_value(name)
387
+ def attributes_with_values(attribute_names)
388
+ attribute_names.index_with do |name|
389
+ _read_attribute(name)
390
+ end
408
391
  end
409
- attrs
410
- end
411
392
 
412
- # Filters the primary keys and readonly attributes from the attribute names.
413
- def attributes_for_update(attribute_names)
414
- attribute_names.reject do |name|
415
- readonly_attribute?(name)
393
+ # Filters the primary keys and readonly attributes from the attribute names.
394
+ def attributes_for_update(attribute_names)
395
+ attribute_names &= self.class.column_names
396
+ attribute_names.delete_if do |name|
397
+ self.class.readonly_attribute?(name)
398
+ end
416
399
  end
417
- end
418
400
 
419
- # Filters out the primary keys, from the attribute names, when the primary
420
- # key is to be generated (e.g. the id attribute has no value).
421
- def attributes_for_create(attribute_names)
422
- attribute_names.reject do |name|
423
- pk_attribute?(name) && id.nil?
401
+ # Filters out the primary keys, from the attribute names, when the primary
402
+ # key is to be generated (e.g. the id attribute has no value).
403
+ def attributes_for_create(attribute_names)
404
+ attribute_names &= self.class.column_names
405
+ attribute_names.delete_if do |name|
406
+ pk_attribute?(name) && id.nil?
407
+ end
424
408
  end
425
- end
426
409
 
427
- def readonly_attribute?(name)
428
- self.class.readonly_attributes.include?(name)
429
- end
410
+ def format_for_inspect(name, value)
411
+ if value.nil?
412
+ value.inspect
413
+ else
414
+ inspected_value = if value.is_a?(String) && value.length > 50
415
+ "#{value[0, 50]}...".inspect
416
+ elsif value.is_a?(Date) || value.is_a?(Time)
417
+ %("#{value.to_s(:inspect)}")
418
+ else
419
+ value.inspect
420
+ end
430
421
 
431
- def pk_attribute?(name)
432
- name == self.class.primary_key
433
- end
422
+ inspection_filter.filter_param(name, inspected_value)
423
+ end
424
+ end
434
425
 
435
- def typecasted_attribute_value(name)
436
- _read_attribute(name)
437
- end
426
+ def pk_attribute?(name)
427
+ name == @primary_key
428
+ end
438
429
  end
439
430
  end