activerecord 4.2.11.2 → 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 (372) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +613 -1638
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +13 -12
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record.rb +41 -22
  8. data/lib/active_record/aggregations.rb +267 -251
  9. data/lib/active_record/association_relation.rb +11 -6
  10. data/lib/active_record/associations.rb +1737 -1597
  11. data/lib/active_record/associations/alias_tracker.rb +29 -35
  12. data/lib/active_record/associations/association.rb +125 -58
  13. data/lib/active_record/associations/association_scope.rb +103 -132
  14. data/lib/active_record/associations/belongs_to_association.rb +65 -60
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  16. data/lib/active_record/associations/builder/association.rb +27 -40
  17. data/lib/active_record/associations/builder/belongs_to.rb +69 -55
  18. data/lib/active_record/associations/builder/collection_association.rb +10 -33
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +52 -66
  20. data/lib/active_record/associations/builder/has_many.rb +8 -4
  21. data/lib/active_record/associations/builder/has_one.rb +46 -5
  22. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  23. data/lib/active_record/associations/collection_association.rb +131 -287
  24. data/lib/active_record/associations/collection_proxy.rb +241 -146
  25. data/lib/active_record/associations/foreign_association.rb +10 -1
  26. data/lib/active_record/associations/has_many_association.rb +34 -97
  27. data/lib/active_record/associations/has_many_through_association.rb +60 -87
  28. data/lib/active_record/associations/has_one_association.rb +61 -49
  29. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  30. data/lib/active_record/associations/join_dependency.rb +137 -167
  31. data/lib/active_record/associations/join_dependency/join_association.rb +38 -86
  32. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  33. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  34. data/lib/active_record/associations/preloader.rb +90 -92
  35. data/lib/active_record/associations/preloader/association.rb +90 -123
  36. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  37. data/lib/active_record/associations/singular_association.rb +18 -39
  38. data/lib/active_record/associations/through_association.rb +38 -18
  39. data/lib/active_record/attribute_assignment.rb +56 -183
  40. data/lib/active_record/attribute_decorators.rb +39 -15
  41. data/lib/active_record/attribute_methods.rb +120 -135
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -8
  43. data/lib/active_record/attribute_methods/dirty.rb +174 -144
  44. data/lib/active_record/attribute_methods/primary_key.rb +91 -83
  45. data/lib/active_record/attribute_methods/query.rb +6 -5
  46. data/lib/active_record/attribute_methods/read.rb +20 -76
  47. data/lib/active_record/attribute_methods/serialization.rb +40 -20
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +58 -36
  49. data/lib/active_record/attribute_methods/write.rb +32 -54
  50. data/lib/active_record/attributes.rb +214 -82
  51. data/lib/active_record/autosave_association.rb +91 -37
  52. data/lib/active_record/base.rb +57 -45
  53. data/lib/active_record/callbacks.rb +100 -74
  54. data/lib/active_record/coders/json.rb +3 -1
  55. data/lib/active_record/coders/yaml_column.rb +24 -12
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +796 -296
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +234 -115
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -23
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +170 -53
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -46
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +356 -227
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +664 -243
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +191 -83
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +460 -204
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +510 -635
  69. data/lib/active_record/connection_adapters/column.rb +56 -43
  70. data/lib/active_record/connection_adapters/connection_specification.rb +174 -152
  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 +200 -0
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -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 +264 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +58 -180
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -114
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
  86. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -58
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +4 -2
  90. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -22
  93. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  94. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
  95. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
  96. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -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 +45 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  100. data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
  101. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
  102. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
  103. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
  104. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  105. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +10 -5
  106. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  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 +50 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +470 -290
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +551 -356
  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 +118 -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 +103 -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 +290 -345
  127. data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
  128. data/lib/active_record/connection_handling.rb +176 -41
  129. data/lib/active_record/core.rb +251 -231
  130. data/lib/active_record/counter_cache.rb +67 -49
  131. data/lib/active_record/database_configurations.rb +233 -0
  132. data/lib/active_record/database_configurations/database_config.rb +37 -0
  133. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  134. data/lib/active_record/database_configurations/url_config.rb +79 -0
  135. data/lib/active_record/define_callbacks.rb +22 -0
  136. data/lib/active_record/dynamic_matchers.rb +87 -105
  137. data/lib/active_record/enum.rb +163 -86
  138. data/lib/active_record/errors.rb +188 -53
  139. data/lib/active_record/explain.rb +23 -11
  140. data/lib/active_record/explain_registry.rb +4 -2
  141. data/lib/active_record/explain_subscriber.rb +10 -5
  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 +153 -0
  146. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  147. data/lib/active_record/fixtures.rb +228 -499
  148. data/lib/active_record/gem_version.rb +6 -4
  149. data/lib/active_record/inheritance.rb +158 -112
  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 +21 -3
  154. data/lib/active_record/locale/en.yml +3 -2
  155. data/lib/active_record/locking/optimistic.rb +87 -96
  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.rb +75 -0
  159. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  160. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  161. data/lib/active_record/migration.rb +621 -303
  162. data/lib/active_record/migration/command_recorder.rb +177 -90
  163. data/lib/active_record/migration/compatibility.rb +244 -0
  164. data/lib/active_record/migration/join_table.rb +8 -6
  165. data/lib/active_record/model_schema.rb +312 -112
  166. data/lib/active_record/nested_attributes.rb +264 -222
  167. data/lib/active_record/no_touching.rb +14 -1
  168. data/lib/active_record/null_relation.rb +24 -37
  169. data/lib/active_record/persistence.rb +557 -125
  170. data/lib/active_record/query_cache.rb +19 -23
  171. data/lib/active_record/querying.rb +43 -29
  172. data/lib/active_record/railtie.rb +143 -44
  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 +328 -185
  177. data/lib/active_record/readonly_attributes.rb +5 -4
  178. data/lib/active_record/reflection.rb +428 -279
  179. data/lib/active_record/relation.rb +518 -341
  180. data/lib/active_record/relation/batches.rb +207 -55
  181. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  182. data/lib/active_record/relation/calculations.rb +267 -253
  183. data/lib/active_record/relation/delegation.rb +70 -80
  184. data/lib/active_record/relation/finder_methods.rb +277 -241
  185. data/lib/active_record/relation/from_clause.rb +26 -0
  186. data/lib/active_record/relation/merger.rb +78 -87
  187. data/lib/active_record/relation/predicate_builder.rb +114 -119
  188. data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -26
  189. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  190. data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
  191. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  192. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  193. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  194. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  195. data/lib/active_record/relation/query_attribute.rb +50 -0
  196. data/lib/active_record/relation/query_methods.rb +575 -394
  197. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  198. data/lib/active_record/relation/spawn_methods.rb +11 -13
  199. data/lib/active_record/relation/where_clause.rb +190 -0
  200. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  201. data/lib/active_record/result.rb +79 -42
  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 -17
  207. data/lib/active_record/scoping.rb +45 -26
  208. data/lib/active_record/scoping/default.rb +101 -85
  209. data/lib/active_record/scoping/named.rb +86 -33
  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 +75 -0
  216. data/lib/active_record/tasks/database_tasks.rb +307 -100
  217. data/lib/active_record/tasks/mysql_database_tasks.rb +55 -99
  218. data/lib/active_record/tasks/postgresql_database_tasks.rb +81 -41
  219. data/lib/active_record/tasks/sqlite_database_tasks.rb +38 -16
  220. data/lib/active_record/test_databases.rb +23 -0
  221. data/lib/active_record/test_fixtures.rb +224 -0
  222. data/lib/active_record/timestamp.rb +86 -40
  223. data/lib/active_record/touch_later.rb +66 -0
  224. data/lib/active_record/transactions.rb +216 -150
  225. data/lib/active_record/translation.rb +3 -1
  226. data/lib/active_record/type.rb +78 -23
  227. data/lib/active_record/type/adapter_specific_registry.rb +129 -0
  228. data/lib/active_record/type/date.rb +4 -45
  229. data/lib/active_record/type/date_time.rb +4 -49
  230. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  231. data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
  232. data/lib/active_record/type/internal/timezone.rb +17 -0
  233. data/lib/active_record/type/json.rb +30 -0
  234. data/lib/active_record/type/serialized.rb +24 -15
  235. data/lib/active_record/type/text.rb +2 -2
  236. data/lib/active_record/type/time.rb +11 -16
  237. data/lib/active_record/type/type_map.rb +15 -17
  238. data/lib/active_record/type/unsigned_integer.rb +9 -7
  239. data/lib/active_record/type_caster.rb +9 -0
  240. data/lib/active_record/type_caster/connection.rb +34 -0
  241. data/lib/active_record/type_caster/map.rb +20 -0
  242. data/lib/active_record/validations.rb +39 -35
  243. data/lib/active_record/validations/absence.rb +25 -0
  244. data/lib/active_record/validations/associated.rb +13 -4
  245. data/lib/active_record/validations/length.rb +26 -0
  246. data/lib/active_record/validations/presence.rb +14 -13
  247. data/lib/active_record/validations/uniqueness.rb +42 -55
  248. data/lib/active_record/version.rb +3 -1
  249. data/lib/arel.rb +51 -0
  250. data/lib/arel/alias_predication.rb +9 -0
  251. data/lib/arel/attributes.rb +22 -0
  252. data/lib/arel/attributes/attribute.rb +37 -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.rb +68 -0
  266. data/lib/arel/nodes/and.rb +32 -0
  267. data/lib/arel/nodes/ascending.rb +23 -0
  268. data/lib/arel/nodes/binary.rb +52 -0
  269. data/lib/arel/nodes/bind_param.rb +36 -0
  270. data/lib/arel/nodes/case.rb +55 -0
  271. data/lib/arel/nodes/casted.rb +50 -0
  272. data/lib/arel/nodes/comment.rb +29 -0
  273. data/lib/arel/nodes/count.rb +12 -0
  274. data/lib/arel/nodes/delete_statement.rb +45 -0
  275. data/lib/arel/nodes/descending.rb +23 -0
  276. data/lib/arel/nodes/equality.rb +18 -0
  277. data/lib/arel/nodes/extract.rb +24 -0
  278. data/lib/arel/nodes/false.rb +16 -0
  279. data/lib/arel/nodes/full_outer_join.rb +8 -0
  280. data/lib/arel/nodes/function.rb +44 -0
  281. data/lib/arel/nodes/grouping.rb +8 -0
  282. data/lib/arel/nodes/in.rb +8 -0
  283. data/lib/arel/nodes/infix_operation.rb +80 -0
  284. data/lib/arel/nodes/inner_join.rb +8 -0
  285. data/lib/arel/nodes/insert_statement.rb +37 -0
  286. data/lib/arel/nodes/join_source.rb +20 -0
  287. data/lib/arel/nodes/matches.rb +18 -0
  288. data/lib/arel/nodes/named_function.rb +23 -0
  289. data/lib/arel/nodes/node.rb +50 -0
  290. data/lib/arel/nodes/node_expression.rb +13 -0
  291. data/lib/arel/nodes/outer_join.rb +8 -0
  292. data/lib/arel/nodes/over.rb +15 -0
  293. data/lib/arel/nodes/regexp.rb +16 -0
  294. data/lib/arel/nodes/right_outer_join.rb +8 -0
  295. data/lib/arel/nodes/select_core.rb +67 -0
  296. data/lib/arel/nodes/select_statement.rb +41 -0
  297. data/lib/arel/nodes/sql_literal.rb +16 -0
  298. data/lib/arel/nodes/string_join.rb +11 -0
  299. data/lib/arel/nodes/table_alias.rb +27 -0
  300. data/lib/arel/nodes/terminal.rb +16 -0
  301. data/lib/arel/nodes/true.rb +16 -0
  302. data/lib/arel/nodes/unary.rb +45 -0
  303. data/lib/arel/nodes/unary_operation.rb +20 -0
  304. data/lib/arel/nodes/unqualified_column.rb +22 -0
  305. data/lib/arel/nodes/update_statement.rb +41 -0
  306. data/lib/arel/nodes/values_list.rb +9 -0
  307. data/lib/arel/nodes/window.rb +126 -0
  308. data/lib/arel/nodes/with.rb +11 -0
  309. data/lib/arel/order_predications.rb +13 -0
  310. data/lib/arel/predications.rb +257 -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.rb +20 -0
  316. data/lib/arel/visitors/depth_first.rb +204 -0
  317. data/lib/arel/visitors/dot.rb +297 -0
  318. data/lib/arel/visitors/ibm_db.rb +34 -0
  319. data/lib/arel/visitors/informix.rb +62 -0
  320. data/lib/arel/visitors/mssql.rb +157 -0
  321. data/lib/arel/visitors/mysql.rb +83 -0
  322. data/lib/arel/visitors/oracle.rb +159 -0
  323. data/lib/arel/visitors/oracle12.rb +66 -0
  324. data/lib/arel/visitors/postgresql.rb +110 -0
  325. data/lib/arel/visitors/sqlite.rb +39 -0
  326. data/lib/arel/visitors/to_sql.rb +889 -0
  327. data/lib/arel/visitors/visitor.rb +46 -0
  328. data/lib/arel/visitors/where_sql.rb +23 -0
  329. data/lib/arel/window_predications.rb +9 -0
  330. data/lib/rails/generators/active_record.rb +7 -5
  331. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -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.rb +31 -1
  334. data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
  335. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  336. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -2
  337. data/lib/rails/generators/active_record/model/model_generator.rb +19 -22
  338. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  339. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  340. metadata +164 -59
  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 -163
  349. data/lib/active_record/attribute_set.rb +0 -81
  350. data/lib/active_record/attribute_set/builder.rb +0 -106
  351. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
  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/infinity.rb +0 -13
  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 -31
  362. data/lib/active_record/type/decimal.rb +0 -64
  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 -59
  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 -40
  369. data/lib/active_record/type/time_value.rb +0 -38
  370. data/lib/active_record/type/value.rb +0 -110
  371. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
  372. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -1,25 +1,28 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
- # = Active Record Belongs To Association
3
4
  module Associations
5
+ # = Active Record Belongs To Association
4
6
  class BelongsToAssociation < SingularAssociation #:nodoc:
5
-
6
7
  def handle_dependency
7
- target.send(options[:dependent]) if load_target
8
- end
8
+ return unless load_target
9
9
 
10
- def replace(record)
11
- if record
12
- raise_on_type_mismatch!(record)
13
- update_counters(record)
14
- replace_keys(record)
15
- set_inverse_instance(record)
16
- @updated = true
10
+ case options[:dependent]
11
+ when :destroy
12
+ target.destroy
13
+ raise ActiveRecord::Rollback unless target.destroyed?
17
14
  else
18
- decrement_counters
19
- remove_keys
15
+ target.send(options[:dependent])
20
16
  end
17
+ end
21
18
 
22
- self.target = record
19
+ def inversed_from(record)
20
+ replace_keys(record)
21
+ super
22
+ end
23
+
24
+ def default(&block)
25
+ writer(owner.instance_exec(&block)) if reader.nil?
23
26
  end
24
27
 
25
28
  def reset
@@ -31,60 +34,74 @@ module ActiveRecord
31
34
  @updated
32
35
  end
33
36
 
34
- def decrement_counters # :nodoc:
35
- with_cache_name { |name| decrement_counter name }
37
+ def decrement_counters
38
+ update_counters(-1)
36
39
  end
37
40
 
38
- def increment_counters # :nodoc:
39
- with_cache_name { |name| increment_counter name }
41
+ def increment_counters
42
+ update_counters(1)
40
43
  end
41
44
 
42
- private
43
-
44
- def find_target?
45
- !loaded? && foreign_key_present? && klass
45
+ def decrement_counters_before_last_save
46
+ if reflection.polymorphic?
47
+ model_was = owner.attribute_before_last_save(reflection.foreign_type).try(:constantize)
48
+ else
49
+ model_was = klass
46
50
  end
47
51
 
48
- def with_cache_name
49
- counter_cache_name = reflection.counter_cache_column
50
- return unless counter_cache_name && owner.persisted?
51
- yield counter_cache_name
52
- end
52
+ foreign_key_was = owner.attribute_before_last_save(reflection.foreign_key)
53
53
 
54
- def update_counters(record)
55
- with_cache_name do |name|
56
- return unless different_target? record
57
- record.class.increment_counter(name, record.id)
58
- decrement_counter name
59
- end
54
+ if foreign_key_was && model_was < ActiveRecord::Base
55
+ update_counters_via_scope(model_was, foreign_key_was, -1)
60
56
  end
57
+ end
61
58
 
62
- def decrement_counter(counter_cache_name)
63
- if foreign_key_present?
64
- klass.decrement_counter(counter_cache_name, target_id)
59
+ def target_changed?
60
+ owner.saved_change_to_attribute?(reflection.foreign_key)
61
+ end
62
+
63
+ private
64
+ def replace(record)
65
+ if record
66
+ raise_on_type_mismatch!(record)
67
+ set_inverse_instance(record)
68
+ @updated = true
65
69
  end
70
+
71
+ replace_keys(record)
72
+
73
+ self.target = record
66
74
  end
67
75
 
68
- def increment_counter(counter_cache_name)
69
- if foreign_key_present?
70
- klass.increment_counter(counter_cache_name, target_id)
71
- if target && !stale_target? && counter_cache_available_in_memory?(counter_cache_name)
72
- target.increment(counter_cache_name)
76
+ def update_counters(by)
77
+ if require_counter_update? && foreign_key_present?
78
+ if target && !stale_target?
79
+ target.increment!(reflection.counter_cache_column, by, touch: reflection.options[:touch])
80
+ else
81
+ update_counters_via_scope(klass, owner._read_attribute(reflection.foreign_key), by)
73
82
  end
74
83
  end
75
84
  end
76
85
 
77
- # Checks whether record is different to the current target, without loading it
78
- def different_target?(record)
79
- record.id != owner._read_attribute(reflection.foreign_key)
86
+ def update_counters_via_scope(klass, foreign_key, by)
87
+ scope = klass.unscoped.where!(primary_key(klass) => foreign_key)
88
+ scope.update_counters(reflection.counter_cache_column => by, touch: reflection.options[:touch])
89
+ end
90
+
91
+ def find_target?
92
+ !loaded? && foreign_key_present? && klass
93
+ end
94
+
95
+ def require_counter_update?
96
+ reflection.counter_cache_column && owner.persisted?
80
97
  end
81
98
 
82
99
  def replace_keys(record)
83
- owner[reflection.foreign_key] = record._read_attribute(reflection.association_primary_key(record.class))
100
+ owner[reflection.foreign_key] = record ? record._read_attribute(primary_key(record.class)) : nil
84
101
  end
85
102
 
86
- def remove_keys
87
- owner[reflection.foreign_key] = nil
103
+ def primary_key(klass)
104
+ reflection.association_primary_key(klass)
88
105
  end
89
106
 
90
107
  def foreign_key_present?
@@ -98,22 +115,10 @@ module ActiveRecord
98
115
  inverse && inverse.has_one?
99
116
  end
100
117
 
101
- def target_id
102
- if options[:primary_key]
103
- owner.send(reflection.name).try(:id)
104
- else
105
- owner._read_attribute(reflection.foreign_key)
106
- end
107
- end
108
-
109
118
  def stale_state
110
- result = owner._read_attribute(reflection.foreign_key)
119
+ result = owner._read_attribute(reflection.foreign_key) { |n| owner.send(:missing_attribute, n, caller) }
111
120
  result && result.to_s
112
121
  end
113
-
114
- def counter_cache_available_in_memory?(counter_cache_name)
115
- target.respond_to?(counter_cache_name)
116
- end
117
122
  end
118
123
  end
119
124
  end
@@ -1,26 +1,22 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
- # = Active Record Belongs To Polymorphic Association
3
4
  module Associations
5
+ # = Active Record Belongs To Polymorphic Association
4
6
  class BelongsToPolymorphicAssociation < BelongsToAssociation #:nodoc:
5
7
  def klass
6
8
  type = owner[reflection.foreign_type]
7
9
  type.presence && type.constantize
8
10
  end
9
11
 
10
- private
12
+ def target_changed?
13
+ super || owner.saved_change_to_attribute?(reflection.foreign_type)
14
+ end
11
15
 
16
+ private
12
17
  def replace_keys(record)
13
18
  super
14
- owner[reflection.foreign_type] = record.class.base_class.name
15
- end
16
-
17
- def remove_keys
18
- super
19
- owner[reflection.foreign_type] = nil
20
- end
21
-
22
- def different_target?(record)
23
- super || record.class != klass
19
+ owner[reflection.foreign_type] = record ? record.class.polymorphic_name : nil
24
20
  end
25
21
 
26
22
  def inverse_reflection_for(record)
@@ -1,4 +1,4 @@
1
- require 'active_support/core_ext/module/attribute_accessors'
1
+ # frozen_string_literal: true
2
2
 
3
3
  # This is the parent Association class which defines the variables
4
4
  # used by all associations.
@@ -11,19 +11,14 @@ require 'active_support/core_ext/module/attribute_accessors'
11
11
  # - CollectionAssociation
12
12
  # - HasManyAssociation
13
13
 
14
- module ActiveRecord::Associations::Builder
14
+ module ActiveRecord::Associations::Builder # :nodoc:
15
15
  class Association #:nodoc:
16
16
  class << self
17
17
  attr_accessor :extensions
18
- # TODO: This class accessor is needed to make activerecord-deprecated_finders work.
19
- # We can move it to a constant in 5.0.
20
- attr_accessor :valid_options
21
18
  end
22
19
  self.extensions = []
23
20
 
24
- self.valid_options = [:class_name, :anonymous_class, :foreign_key, :validate]
25
-
26
- attr_reader :name, :scope, :options
21
+ VALID_OPTIONS = [:class_name, :anonymous_class, :foreign_key, :validate] # :nodoc:
27
22
 
28
23
  def self.build(model, name, scope, options, &block)
29
24
  if model.dangerous_attribute_method?(name)
@@ -32,57 +27,47 @@ module ActiveRecord::Associations::Builder
32
27
  "Please choose a different association name."
33
28
  end
34
29
 
35
- builder = create_builder model, name, scope, options, &block
36
- reflection = builder.build(model)
30
+ reflection = create_reflection(model, name, scope, options, &block)
37
31
  define_accessors model, reflection
38
32
  define_callbacks model, reflection
39
33
  define_validations model, reflection
40
- builder.define_extensions model
41
34
  reflection
42
35
  end
43
36
 
44
- def self.create_builder(model, name, scope, options, &block)
37
+ def self.create_reflection(model, name, scope, options, &block)
45
38
  raise ArgumentError, "association names must be a Symbol" unless name.kind_of?(Symbol)
46
39
 
47
- new(model, name, scope, options, &block)
48
- end
40
+ validate_options(options)
49
41
 
50
- def initialize(model, name, scope, options)
51
- # TODO: Move this to create_builder as soon we drop support to activerecord-deprecated_finders.
52
- if scope.is_a?(Hash)
53
- options = scope
54
- scope = nil
55
- end
42
+ extension = define_extensions(model, name, &block)
43
+ options[:extend] = [*options[:extend], extension] if extension
56
44
 
57
- # TODO: Remove this model argument as soon we drop support to activerecord-deprecated_finders.
58
- @name = name
59
- @scope = scope
60
- @options = options
45
+ scope = build_scope(scope)
61
46
 
62
- validate_options
47
+ ActiveRecord::Reflection.create(macro, name, scope, options, model)
48
+ end
63
49
 
50
+ def self.build_scope(scope)
64
51
  if scope && scope.arity == 0
65
- @scope = proc { instance_exec(&scope) }
52
+ proc { instance_exec(&scope) }
53
+ else
54
+ scope
66
55
  end
67
56
  end
68
57
 
69
- def build(model)
70
- ActiveRecord::Reflection.create(macro, name, scope, options, model)
71
- end
72
-
73
- def macro
58
+ def self.macro
74
59
  raise NotImplementedError
75
60
  end
76
61
 
77
- def valid_options
78
- Association.valid_options + Association.extensions.flat_map(&:valid_options)
62
+ def self.valid_options(options)
63
+ VALID_OPTIONS + Association.extensions.flat_map(&:valid_options)
79
64
  end
80
65
 
81
- def validate_options
82
- options.assert_valid_keys(valid_options)
66
+ def self.validate_options(options)
67
+ options.assert_valid_keys(valid_options(options))
83
68
  end
84
69
 
85
- def define_extensions(model)
70
+ def self.define_extensions(model, name)
86
71
  end
87
72
 
88
73
  def self.define_callbacks(model, reflection)
@@ -111,8 +96,8 @@ module ActiveRecord::Associations::Builder
111
96
 
112
97
  def self.define_readers(mixin, name)
113
98
  mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
114
- def #{name}(*args)
115
- association(:#{name}).reader(*args)
99
+ def #{name}
100
+ association(:#{name}).reader
116
101
  end
117
102
  CODE
118
103
  end
@@ -133,8 +118,6 @@ module ActiveRecord::Associations::Builder
133
118
  raise NotImplementedError
134
119
  end
135
120
 
136
- private
137
-
138
121
  def self.check_dependent_options(dependent)
139
122
  unless valid_dependent_options.include? dependent
140
123
  raise ArgumentError, "The :dependent option must be one of #{valid_dependent_options}, but is :#{dependent}"
@@ -145,5 +128,9 @@ module ActiveRecord::Associations::Builder
145
128
  name = reflection.name
146
129
  model.before_destroy lambda { |o| o.association(name).handle_dependency }
147
130
  end
131
+
132
+ private_class_method :build_scope, :macro, :valid_options, :validate_options, :define_extensions,
133
+ :define_callbacks, :define_accessors, :define_readers, :define_writers, :define_validations,
134
+ :valid_dependent_options, :check_dependent_options, :add_destroy_callbacks
148
135
  end
149
136
  end
@@ -1,11 +1,13 @@
1
- module ActiveRecord::Associations::Builder
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord::Associations::Builder # :nodoc:
2
4
  class BelongsTo < SingularAssociation #:nodoc:
3
- def macro
5
+ def self.macro
4
6
  :belongs_to
5
7
  end
6
8
 
7
- def valid_options
8
- super + [:foreign_type, :polymorphic, :touch, :counter_cache]
9
+ def self.valid_options(options)
10
+ super + [:polymorphic, :touch, :counter_cache, :optional, :default]
9
11
  end
10
12
 
11
13
  def self.valid_dependent_options
@@ -16,70 +18,46 @@ module ActiveRecord::Associations::Builder
16
18
  super
17
19
  add_counter_cache_callbacks(model, reflection) if reflection.options[:counter_cache]
18
20
  add_touch_callbacks(model, reflection) if reflection.options[:touch]
19
- end
20
-
21
- def self.define_accessors(mixin, reflection)
22
- super
23
- add_counter_cache_methods mixin
24
- end
25
-
26
- private
27
-
28
- def self.add_counter_cache_methods(mixin)
29
- return if mixin.method_defined? :belongs_to_counter_cache_after_update
30
-
31
- mixin.class_eval do
32
- def belongs_to_counter_cache_after_update(reflection)
33
- foreign_key = reflection.foreign_key
34
- cache_column = reflection.counter_cache_column
35
-
36
- if (@_after_create_counter_called ||= false)
37
- @_after_create_counter_called = false
38
- elsif attribute_changed?(foreign_key) && !new_record? && reflection.constructable?
39
- model = reflection.klass
40
- foreign_key_was = attribute_was foreign_key
41
- foreign_key = attribute foreign_key
42
-
43
- if foreign_key && model.respond_to?(:increment_counter)
44
- model.increment_counter(cache_column, foreign_key)
45
- end
46
- if foreign_key_was && model.respond_to?(:decrement_counter)
47
- model.decrement_counter(cache_column, foreign_key_was)
48
- end
49
- end
50
- end
51
- end
21
+ add_default_callbacks(model, reflection) if reflection.options[:default]
52
22
  end
53
23
 
54
24
  def self.add_counter_cache_callbacks(model, reflection)
55
25
  cache_column = reflection.counter_cache_column
56
26
 
57
27
  model.after_update lambda { |record|
58
- record.belongs_to_counter_cache_after_update(reflection)
28
+ association = association(reflection.name)
29
+
30
+ if association.target_changed?
31
+ association.increment_counters
32
+ association.decrement_counters_before_last_save
33
+ end
59
34
  }
60
35
 
61
36
  klass = reflection.class_name.safe_constantize
62
37
  klass.attr_readonly cache_column if klass && klass.respond_to?(:attr_readonly)
63
38
  end
64
39
 
65
- def self.touch_record(o, foreign_key, name, touch) # :nodoc:
66
- old_foreign_id = o.changed_attributes[foreign_key]
40
+ def self.touch_record(o, changes, foreign_key, name, touch, touch_method) # :nodoc:
41
+ old_foreign_id = changes[foreign_key] && changes[foreign_key].first
67
42
 
68
43
  if old_foreign_id
69
44
  association = o.association(name)
70
45
  reflection = association.reflection
71
46
  if reflection.polymorphic?
72
- klass = o.public_send("#{reflection.foreign_type}_was").constantize
47
+ foreign_type = reflection.foreign_type
48
+ klass = changes[foreign_type] && changes[foreign_type].first || o.public_send(foreign_type)
49
+ klass = klass.constantize
73
50
  else
74
51
  klass = association.klass
75
52
  end
76
- old_record = klass.find_by(klass.primary_key => old_foreign_id)
53
+ primary_key = reflection.association_primary_key(klass)
54
+ old_record = klass.find_by(primary_key => old_foreign_id)
77
55
 
78
56
  if old_record
79
57
  if touch != true
80
- old_record.touch touch
58
+ old_record.send(touch_method, touch)
81
59
  else
82
- old_record.touch
60
+ old_record.send(touch_method)
83
61
  end
84
62
  end
85
63
  end
@@ -87,30 +65,66 @@ module ActiveRecord::Associations::Builder
87
65
  record = o.send name
88
66
  if record && record.persisted?
89
67
  if touch != true
90
- record.touch touch
68
+ record.send(touch_method, touch)
91
69
  else
92
- record.touch
70
+ record.send(touch_method)
93
71
  end
94
72
  end
95
73
  end
96
74
 
97
75
  def self.add_touch_callbacks(model, reflection)
98
76
  foreign_key = reflection.foreign_key
99
- n = reflection.name
77
+ name = reflection.name
100
78
  touch = reflection.options[:touch]
101
79
 
102
- callback = lambda { |record|
103
- BelongsTo.touch_record(record, foreign_key, n, touch)
104
- }
80
+ callback = lambda { |changes_method| lambda { |record|
81
+ BelongsTo.touch_record(record, record.send(changes_method), foreign_key, name, touch, belongs_to_touch_method)
82
+ }}
83
+
84
+ if reflection.counter_cache_column
85
+ touch_callback = callback.(:saved_changes)
86
+ update_callback = lambda { |record|
87
+ instance_exec(record, &touch_callback) unless association(reflection.name).target_changed?
88
+ }
89
+ model.after_update update_callback, if: :saved_changes?
90
+ else
91
+ model.after_create callback.(:saved_changes), if: :saved_changes?
92
+ model.after_update callback.(:saved_changes), if: :saved_changes?
93
+ model.after_destroy callback.(:changes_to_save)
94
+ end
105
95
 
106
- model.after_save callback, if: :changed?
107
- model.after_touch callback
108
- model.after_destroy callback
96
+ model.after_touch callback.(:changes_to_save)
97
+ end
98
+
99
+ def self.add_default_callbacks(model, reflection)
100
+ model.before_validation lambda { |o|
101
+ o.association(reflection.name).default(&reflection.options[:default])
102
+ }
109
103
  end
110
104
 
111
105
  def self.add_destroy_callbacks(model, reflection)
112
- name = reflection.name
113
- model.after_destroy lambda { |o| o.association(name).handle_dependency }
106
+ model.after_destroy lambda { |o| o.association(reflection.name).handle_dependency }
114
107
  end
108
+
109
+ def self.define_validations(model, reflection)
110
+ if reflection.options.key?(:required)
111
+ reflection.options[:optional] = !reflection.options.delete(:required)
112
+ end
113
+
114
+ if reflection.options[:optional].nil?
115
+ required = model.belongs_to_required_by_default
116
+ else
117
+ required = !reflection.options[:optional]
118
+ end
119
+
120
+ super
121
+
122
+ if required
123
+ model.validates_presence_of reflection.name, message: :required
124
+ end
125
+ end
126
+
127
+ private_class_method :macro, :valid_options, :valid_dependent_options, :define_callbacks, :define_validations,
128
+ :add_counter_cache_callbacks, :add_touch_callbacks, :add_default_callbacks, :add_destroy_callbacks
115
129
  end
116
130
  end