activerecord 4.2.9 → 6.1.4.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 (374) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +964 -1382
  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 +266 -251
  8. data/lib/active_record/association_relation.rb +40 -15
  9. data/lib/active_record/associations/alias_tracker.rb +40 -43
  10. data/lib/active_record/associations/association.rb +162 -69
  11. data/lib/active_record/associations/association_scope.rb +105 -130
  12. data/lib/active_record/associations/belongs_to_association.rb +83 -65
  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 -37
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +49 -66
  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 +148 -287
  22. data/lib/active_record/associations/collection_proxy.rb +252 -150
  23. data/lib/active_record/associations/foreign_association.rb +23 -1
  24. data/lib/active_record/associations/has_many_association.rb +56 -98
  25. data/lib/active_record/associations/has_many_through_association.rb +68 -89
  26. data/lib/active_record/associations/has_one_association.rb +73 -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 -81
  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 +174 -169
  32. data/lib/active_record/associations/preloader/association.rb +108 -115
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +97 -94
  35. data/lib/active_record/associations/singular_association.rb +18 -39
  36. data/lib/active_record/associations/through_association.rb +39 -19
  37. data/lib/active_record/associations.rb +1845 -1598
  38. data/lib/active_record/attribute_assignment.rb +59 -185
  39. data/lib/active_record/attribute_methods/before_type_cast.rb +18 -10
  40. data/lib/active_record/attribute_methods/dirty.rb +168 -148
  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 +55 -36
  46. data/lib/active_record/attribute_methods/write.rb +24 -55
  47. data/lib/active_record/attribute_methods.rb +149 -154
  48. data/lib/active_record/attributes.rb +234 -78
  49. data/lib/active_record/autosave_association.rb +133 -60
  50. data/lib/active_record/base.rb +46 -46
  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 +34 -13
  54. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +887 -323
  55. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -41
  56. data/lib/active_record/connection_adapters/abstract/database_statements.rb +292 -124
  57. data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -24
  58. data/lib/active_record/connection_adapters/abstract/quoting.rb +177 -60
  59. data/lib/active_record/connection_adapters/abstract/savepoints.rb +8 -6
  60. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +157 -93
  61. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +473 -255
  62. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  63. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +869 -286
  64. data/lib/active_record/connection_adapters/abstract/transaction.rb +257 -91
  65. data/lib/active_record/connection_adapters/abstract_adapter.rb +483 -230
  66. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +557 -640
  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 +194 -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 +268 -0
  78. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
  79. data/lib/active_record/connection_adapters/mysql2_adapter.rb +80 -192
  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 +75 -160
  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 -58
  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 +4 -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 +14 -19
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  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 -5
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  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 +145 -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 +496 -298
  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 +588 -375
  119. data/lib/active_record/connection_adapters/schema_cache.rb +167 -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 +144 -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 -373
  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 +458 -241
  133. data/lib/active_record/counter_cache.rb +70 -49
  134. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -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 +272 -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 +211 -92
  143. data/lib/active_record/errors.rb +224 -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 +10 -5
  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 +275 -500
  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 +62 -0
  158. data/lib/active_record/legacy_yaml_adapter.rb +27 -5
  159. data/lib/active_record/locale/en.yml +3 -2
  160. data/lib/active_record/locking/optimistic.rb +98 -92
  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 +295 -0
  168. data/lib/active_record/migration/join_table.rb +8 -7
  169. data/lib/active_record/migration.rb +673 -325
  170. data/lib/active_record/model_schema.rb +418 -113
  171. data/lib/active_record/nested_attributes.rb +263 -224
  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 +572 -136
  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 +170 -51
  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 +523 -199
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +454 -291
  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 +324 -249
  186. data/lib/active_record/relation/delegation.rb +76 -84
  187. data/lib/active_record/relation/finder_methods.rb +316 -242
  188. data/lib/active_record/relation/from_clause.rb +30 -0
  189. data/lib/active_record/relation/merger.rb +95 -103
  190. data/lib/active_record/relation/predicate_builder/array_handler.rb +26 -26
  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 +136 -122
  197. data/lib/active_record/relation/query_attribute.rb +50 -0
  198. data/lib/active_record/relation/query_methods.rb +757 -413
  199. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  200. data/lib/active_record/relation/spawn_methods.rb +18 -20
  201. data/lib/active_record/relation/where_clause.rb +239 -0
  202. data/lib/active_record/relation.rb +554 -343
  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 -23
  209. data/lib/active_record/scoping/default.rb +96 -83
  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 +128 -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 +364 -130
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +67 -113
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +86 -49
  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 +287 -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 +182 -163
  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 -45
  231. data/lib/active_record/type/date_time.rb +4 -49
  232. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  233. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  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 +27 -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 +63 -56
  251. data/lib/active_record/validations.rb +39 -35
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/active_record.rb +42 -29
  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 -4
  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/model/templates/{module.rb → module.rb.tt} +0 -0
  339. data/lib/rails/generators/active_record.rb +7 -5
  340. metadata +172 -65
  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_decorators.rb +0 -66
  350. data/lib/active_record/attribute_set/builder.rb +0 -106
  351. data/lib/active_record/attribute_set.rb +0 -81
  352. data/lib/active_record/connection_adapters/connection_specification.rb +0 -275
  353. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  354. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  355. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  356. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  357. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  358. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  359. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  360. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  361. data/lib/active_record/type/big_integer.rb +0 -13
  362. data/lib/active_record/type/binary.rb +0 -50
  363. data/lib/active_record/type/boolean.rb +0 -31
  364. data/lib/active_record/type/decimal.rb +0 -64
  365. data/lib/active_record/type/decorator.rb +0 -14
  366. data/lib/active_record/type/float.rb +0 -19
  367. data/lib/active_record/type/integer.rb +0 -59
  368. data/lib/active_record/type/mutable.rb +0 -16
  369. data/lib/active_record/type/numeric.rb +0 -36
  370. data/lib/active_record/type/string.rb +0 -40
  371. data/lib/active_record/type/time_value.rb +0 -38
  372. data/lib/active_record/type/value.rb +0 -110
  373. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
  374. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -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,16 @@ 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 = [
22
+ :class_name, :anonymous_class, :primary_key, :foreign_key, :dependent, :validate, :inverse_of, :strict_loading
23
+ ].freeze # :nodoc:
27
24
 
28
25
  def self.build(model, name, scope, options, &block)
29
26
  if model.dangerous_attribute_method?(name)
@@ -32,63 +29,54 @@ module ActiveRecord::Associations::Builder
32
29
  "Please choose a different association name."
33
30
  end
34
31
 
35
- builder = create_builder model, name, scope, options, &block
36
- reflection = builder.build(model)
32
+ reflection = create_reflection(model, name, scope, options, &block)
37
33
  define_accessors model, reflection
38
34
  define_callbacks model, reflection
39
35
  define_validations model, reflection
40
- builder.define_extensions model
41
36
  reflection
42
37
  end
43
38
 
44
- def self.create_builder(model, name, scope, options, &block)
39
+ def self.create_reflection(model, name, scope, options, &block)
45
40
  raise ArgumentError, "association names must be a Symbol" unless name.kind_of?(Symbol)
46
41
 
47
- new(model, name, scope, options, &block)
48
- end
42
+ validate_options(options)
49
43
 
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
44
+ extension = define_extensions(model, name, &block)
45
+ options[:extend] = [*options[:extend], extension] if extension
56
46
 
57
- # TODO: Remove this model argument as soon we drop support to activerecord-deprecated_finders.
58
- @name = name
59
- @scope = scope
60
- @options = options
47
+ scope = build_scope(scope)
61
48
 
62
- validate_options
49
+ ActiveRecord::Reflection.create(macro, name, scope, options, model)
50
+ end
63
51
 
52
+ def self.build_scope(scope)
64
53
  if scope && scope.arity == 0
65
- @scope = proc { instance_exec(&scope) }
54
+ proc { instance_exec(&scope) }
55
+ else
56
+ scope
66
57
  end
67
58
  end
68
59
 
69
- def build(model)
70
- ActiveRecord::Reflection.create(macro, name, scope, options, model)
71
- end
72
-
73
- def macro
60
+ def self.macro
74
61
  raise NotImplementedError
75
62
  end
76
63
 
77
- def valid_options
78
- Association.valid_options + Association.extensions.flat_map(&:valid_options)
64
+ def self.valid_options(options)
65
+ VALID_OPTIONS + Association.extensions.flat_map(&:valid_options)
79
66
  end
80
67
 
81
- def validate_options
82
- options.assert_valid_keys(valid_options)
68
+ def self.validate_options(options)
69
+ options.assert_valid_keys(valid_options(options))
83
70
  end
84
71
 
85
- def define_extensions(model)
72
+ def self.define_extensions(model, name)
86
73
  end
87
74
 
88
75
  def self.define_callbacks(model, reflection)
89
76
  if dependent = reflection.options[:dependent]
90
- check_dependent_options(dependent)
77
+ check_dependent_options(dependent, model)
91
78
  add_destroy_callbacks(model, reflection)
79
+ add_after_commit_jobs_callback(model, dependent)
92
80
  end
93
81
 
94
82
  Association.extensions.each do |extension|
@@ -111,8 +99,8 @@ module ActiveRecord::Associations::Builder
111
99
 
112
100
  def self.define_readers(mixin, name)
113
101
  mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
114
- def #{name}(*args)
115
- association(:#{name}).reader(*args)
102
+ def #{name}
103
+ association(:#{name}).reader
116
104
  end
117
105
  CODE
118
106
  end
@@ -133,9 +121,11 @@ module ActiveRecord::Associations::Builder
133
121
  raise NotImplementedError
134
122
  end
135
123
 
136
- private
137
-
138
- def self.check_dependent_options(dependent)
124
+ def self.check_dependent_options(dependent, model)
125
+ if dependent == :destroy_async && !model.destroy_association_async_job
126
+ err_message = "ActiveJob is required to use destroy_async on associations"
127
+ raise ActiveRecord::ActiveJobRequiredError, err_message
128
+ end
139
129
  unless valid_dependent_options.include? dependent
140
130
  raise ArgumentError, "The :dependent option must be one of #{valid_dependent_options}, but is :#{dependent}"
141
131
  end
@@ -143,7 +133,31 @@ module ActiveRecord::Associations::Builder
143
133
 
144
134
  def self.add_destroy_callbacks(model, reflection)
145
135
  name = reflection.name
146
- model.before_destroy lambda { |o| o.association(name).handle_dependency }
136
+ model.before_destroy(->(o) { o.association(name).handle_dependency })
137
+ end
138
+
139
+ def self.add_after_commit_jobs_callback(model, dependent)
140
+ if dependent == :destroy_async
141
+ mixin = model.generated_association_methods
142
+
143
+ unless mixin.method_defined?(:_after_commit_jobs)
144
+ model.after_commit(-> do
145
+ _after_commit_jobs.each do |job_class, job_arguments|
146
+ job_class.perform_later(**job_arguments)
147
+ end
148
+ end)
149
+
150
+ mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
151
+ def _after_commit_jobs
152
+ @_after_commit_jobs ||= []
153
+ end
154
+ CODE
155
+ end
156
+ end
147
157
  end
158
+
159
+ private_class_method :build_scope, :macro, :valid_options, :validate_options, :define_extensions,
160
+ :define_callbacks, :define_accessors, :define_readers, :define_writers, :define_validations,
161
+ :valid_dependent_options, :check_dependent_options, :add_destroy_callbacks, :add_after_commit_jobs_callback
148
162
  end
149
163
  end
@@ -1,116 +1,133 @@
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
+ valid = super + [:polymorphic, :counter_cache, :optional, :default]
11
+ valid += [:foreign_type] if options[:polymorphic]
12
+ valid += [:ensuring_owner_was] if options[:dependent] == :destroy_async
13
+ valid
9
14
  end
10
15
 
11
16
  def self.valid_dependent_options
12
- [:destroy, :delete]
17
+ [:destroy, :delete, :destroy_async]
13
18
  end
14
19
 
15
20
  def self.define_callbacks(model, reflection)
16
21
  super
17
22
  add_counter_cache_callbacks(model, reflection) if reflection.options[:counter_cache]
18
23
  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
24
+ add_default_callbacks(model, reflection) if reflection.options[:default]
52
25
  end
53
26
 
54
27
  def self.add_counter_cache_callbacks(model, reflection)
55
28
  cache_column = reflection.counter_cache_column
56
29
 
57
30
  model.after_update lambda { |record|
58
- record.belongs_to_counter_cache_after_update(reflection)
31
+ association = association(reflection.name)
32
+
33
+ if association.target_changed?
34
+ association.increment_counters
35
+ association.decrement_counters_before_last_save
36
+ end
59
37
  }
60
38
 
61
39
  klass = reflection.class_name.safe_constantize
62
40
  klass.attr_readonly cache_column if klass && klass.respond_to?(:attr_readonly)
63
41
  end
64
42
 
65
- def self.touch_record(o, foreign_key, name, touch) # :nodoc:
66
- old_foreign_id = o.changed_attributes[foreign_key]
43
+ def self.touch_record(o, changes, foreign_key, name, touch, touch_method) # :nodoc:
44
+ old_foreign_id = changes[foreign_key] && changes[foreign_key].first
67
45
 
68
46
  if old_foreign_id
69
47
  association = o.association(name)
70
48
  reflection = association.reflection
71
49
  if reflection.polymorphic?
72
- klass = o.public_send("#{reflection.foreign_type}_was").constantize
50
+ foreign_type = reflection.foreign_type
51
+ klass = changes[foreign_type] && changes[foreign_type].first || o.public_send(foreign_type)
52
+ klass = klass.constantize
73
53
  else
74
54
  klass = association.klass
75
55
  end
76
- old_record = klass.find_by(klass.primary_key => old_foreign_id)
56
+ primary_key = reflection.association_primary_key(klass)
57
+ old_record = klass.find_by(primary_key => old_foreign_id)
77
58
 
78
59
  if old_record
79
60
  if touch != true
80
- old_record.touch touch
61
+ old_record.public_send(touch_method, touch)
81
62
  else
82
- old_record.touch
63
+ old_record.public_send(touch_method)
83
64
  end
84
65
  end
85
66
  end
86
67
 
87
- record = o.send name
68
+ record = o.public_send name
88
69
  if record && record.persisted?
89
70
  if touch != true
90
- record.touch touch
71
+ record.public_send(touch_method, touch)
91
72
  else
92
- record.touch
73
+ record.public_send(touch_method)
93
74
  end
94
75
  end
95
76
  end
96
77
 
97
78
  def self.add_touch_callbacks(model, reflection)
98
79
  foreign_key = reflection.foreign_key
99
- n = reflection.name
80
+ name = reflection.name
100
81
  touch = reflection.options[:touch]
101
82
 
102
- callback = lambda { |record|
103
- BelongsTo.touch_record(record, foreign_key, n, touch)
104
- }
83
+ callback = lambda { |changes_method| lambda { |record|
84
+ BelongsTo.touch_record(record, record.send(changes_method), foreign_key, name, touch, belongs_to_touch_method)
85
+ }}
86
+
87
+ if reflection.counter_cache_column
88
+ touch_callback = callback.(:saved_changes)
89
+ update_callback = lambda { |record|
90
+ instance_exec(record, &touch_callback) unless association(reflection.name).target_changed?
91
+ }
92
+ model.after_update update_callback, if: :saved_changes?
93
+ else
94
+ model.after_create callback.(:saved_changes), if: :saved_changes?
95
+ model.after_update callback.(:saved_changes), if: :saved_changes?
96
+ model.after_destroy callback.(:changes_to_save)
97
+ end
105
98
 
106
- model.after_save callback, if: :changed?
107
- model.after_touch callback
108
- model.after_destroy callback
99
+ model.after_touch callback.(:changes_to_save)
100
+ end
101
+
102
+ def self.add_default_callbacks(model, reflection)
103
+ model.before_validation lambda { |o|
104
+ o.association(reflection.name).default(&reflection.options[:default])
105
+ }
109
106
  end
110
107
 
111
108
  def self.add_destroy_callbacks(model, reflection)
112
- name = reflection.name
113
- model.after_destroy lambda { |o| o.association(name).handle_dependency }
109
+ model.after_destroy lambda { |o| o.association(reflection.name).handle_dependency }
114
110
  end
111
+
112
+ def self.define_validations(model, reflection)
113
+ if reflection.options.key?(:required)
114
+ reflection.options[:optional] = !reflection.options.delete(:required)
115
+ end
116
+
117
+ if reflection.options[:optional].nil?
118
+ required = model.belongs_to_required_by_default
119
+ else
120
+ required = !reflection.options[:optional]
121
+ end
122
+
123
+ super
124
+
125
+ if required
126
+ model.validates_presence_of reflection.name, message: :required
127
+ end
128
+ end
129
+
130
+ private_class_method :macro, :valid_options, :valid_dependent_options, :define_callbacks, :define_validations,
131
+ :add_counter_cache_callbacks, :add_touch_callbacks, :add_default_callbacks, :add_destroy_callbacks
115
132
  end
116
133
  end
@@ -1,26 +1,13 @@
1
- # This class is inherited by the has_many and has_many_and_belongs_to_many association classes
1
+ # frozen_string_literal: true
2
2
 
3
- require 'active_record/associations'
3
+ require "active_record/associations"
4
4
 
5
- module ActiveRecord::Associations::Builder
5
+ module ActiveRecord::Associations::Builder # :nodoc:
6
6
  class CollectionAssociation < Association #:nodoc:
7
-
8
7
  CALLBACKS = [:before_add, :after_add, :before_remove, :after_remove]
9
8
 
10
- def valid_options
11
- super + [:table_name, :before_add,
12
- :after_add, :before_remove, :after_remove, :extend]
13
- end
14
-
15
- attr_reader :block_extension
16
-
17
- def initialize(model, name, scope, options)
18
- super
19
- @mod = nil
20
- if block_given?
21
- @mod = Module.new(&Proc.new)
22
- @scope = wrap_scope @scope, @mod
23
- end
9
+ def self.valid_options(options)
10
+ super + [:before_add, :after_add, :before_remove, :after_remove, :extend]
24
11
  end
25
12
 
26
13
  def self.define_callbacks(model, reflection)
@@ -32,18 +19,21 @@ module ActiveRecord::Associations::Builder
32
19
  }
33
20
  end
34
21
 
35
- def define_extensions(model)
36
- if @mod
37
- extension_module_name = "#{model.name.demodulize}#{name.to_s.camelize}AssociationExtension"
38
- model.parent.const_set(extension_module_name, @mod)
22
+ def self.define_extensions(model, name, &block)
23
+ if block_given?
24
+ extension_module_name = "#{name.to_s.camelize}AssociationExtension"
25
+ extension = Module.new(&block)
26
+ model.const_set(extension_module_name, extension)
39
27
  end
40
28
  end
41
29
 
42
30
  def self.define_callback(model, callback_name, name, options)
43
31
  full_callback_name = "#{callback_name}_for_#{name}"
44
32
 
45
- # TODO : why do i need method_defined? I think its because of the inheritance chain
46
- model.class_attribute full_callback_name unless model.method_defined?(full_callback_name)
33
+ unless model.method_defined?(full_callback_name)
34
+ model.class_attribute(full_callback_name, instance_accessor: false, instance_predicate: false)
35
+ end
36
+
47
37
  callbacks = Array(options[callback_name.to_sym]).map do |callback|
48
38
  case callback
49
39
  when Symbol
@@ -78,18 +68,6 @@ module ActiveRecord::Associations::Builder
78
68
  CODE
79
69
  end
80
70
 
81
- private
82
-
83
- def wrap_scope(scope, mod)
84
- if scope
85
- if scope.arity > 0
86
- proc { |owner| instance_exec(owner, &scope).extending(mod) }
87
- else
88
- proc { instance_exec(&scope).extending(mod) }
89
- end
90
- else
91
- proc { extending(mod) }
92
- end
93
- end
71
+ private_class_method :valid_options, :define_callback, :define_extensions, :define_readers, :define_writers
94
72
  end
95
73
  end
@@ -1,38 +1,7 @@
1
- module ActiveRecord::Associations::Builder
2
- class HasAndBelongsToMany # :nodoc:
3
- class JoinTableResolver
4
- KnownTable = Struct.new :join_table
5
-
6
- class KnownClass
7
- def initialize(lhs_class, rhs_class_name)
8
- @lhs_class = lhs_class
9
- @rhs_class_name = rhs_class_name
10
- @join_table = nil
11
- end
12
-
13
- def join_table
14
- @join_table ||= [@lhs_class.table_name, klass.table_name].sort.join("\0").gsub(/^(.*[._])(.+)\0\1(.+)/, '\1\2_\3').tr("\0", "_")
15
- end
16
-
17
- private
18
-
19
- def klass
20
- @lhs_class.send(:compute_type, @rhs_class_name)
21
- end
22
- end
23
-
24
- def self.build(lhs_class, name, options)
25
- if options[:join_table]
26
- KnownTable.new options[:join_table].to_s
27
- else
28
- class_name = options.fetch(:class_name) {
29
- name.to_s.camelize.singularize
30
- }
31
- KnownClass.new lhs_class, class_name
32
- end
33
- end
34
- end
1
+ # frozen_string_literal: true
35
2
 
3
+ module ActiveRecord::Associations::Builder # :nodoc:
4
+ class HasAndBelongsToMany # :nodoc:
36
5
  attr_reader :lhs_model, :association_name, :options
37
6
 
38
7
  def initialize(association_name, lhs_model, options)
@@ -42,10 +11,8 @@ module ActiveRecord::Associations::Builder
42
11
  end
43
12
 
44
13
  def through_model
45
- habtm = JoinTableResolver.build lhs_model, association_name, options
46
-
47
14
  join_model = Class.new(ActiveRecord::Base) {
48
- class << self;
15
+ class << self
49
16
  attr_accessor :left_model
50
17
  attr_accessor :name
51
18
  attr_accessor :table_name_resolver
@@ -54,7 +21,9 @@ module ActiveRecord::Associations::Builder
54
21
  end
55
22
 
56
23
  def self.table_name
57
- table_name_resolver.join_table
24
+ # Table name needs to be resolved lazily
25
+ # because RHS class might not have been loaded
26
+ @table_name ||= table_name_resolver.call
58
27
  end
59
28
 
60
29
  def self.compute_type(class_name)
@@ -62,13 +31,13 @@ module ActiveRecord::Associations::Builder
62
31
  end
63
32
 
64
33
  def self.add_left_association(name, options)
65
- belongs_to name, options
34
+ belongs_to name, required: false, **options
66
35
  self.left_reflection = _reflect_on_association(name)
67
36
  end
68
37
 
69
38
  def self.add_right_association(name, options)
70
39
  rhs_name = name.to_s.singularize.to_sym
71
- belongs_to rhs_name, options
40
+ belongs_to rhs_name, required: false, **options
72
41
  self.right_reflection = _reflect_on_association(rhs_name)
73
42
  end
74
43
 
@@ -76,10 +45,14 @@ module ActiveRecord::Associations::Builder
76
45
  left_model.retrieve_connection
77
46
  end
78
47
 
48
+ private
49
+ def self.suppress_composite_primary_key(pk)
50
+ pk unless pk.is_a?(Array)
51
+ end
79
52
  }
80
53
 
81
54
  join_model.name = "HABTM_#{association_name.to_s.camelize}"
82
- join_model.table_name_resolver = habtm
55
+ join_model.table_name_resolver = -> { table_name }
83
56
  join_model.left_model = lhs_model
84
57
 
85
58
  join_model.add_left_association :left_side, anonymous_class: lhs_model
@@ -89,40 +62,50 @@ module ActiveRecord::Associations::Builder
89
62
 
90
63
  def middle_reflection(join_model)
91
64
  middle_name = [lhs_model.name.downcase.pluralize,
92
- association_name].join('_').gsub(/::/, '_').to_sym
65
+ association_name.to_s].sort.join("_").gsub("::", "_").to_sym
93
66
  middle_options = middle_options join_model
94
- hm_builder = HasMany.create_builder(lhs_model,
95
- middle_name,
96
- nil,
97
- middle_options)
98
- hm_builder.build lhs_model
67
+
68
+ HasMany.create_reflection(lhs_model,
69
+ middle_name,
70
+ nil,
71
+ middle_options)
99
72
  end
100
73
 
101
74
  private
75
+ def middle_options(join_model)
76
+ middle_options = {}
77
+ middle_options[:class_name] = "#{lhs_model.name}::#{join_model.name}"
78
+ if options.key? :foreign_key
79
+ middle_options[:foreign_key] = options[:foreign_key]
80
+ end
81
+ middle_options
82
+ end
102
83
 
103
- def middle_options(join_model)
104
- middle_options = {}
105
- middle_options[:class_name] = "#{lhs_model.name}::#{join_model.name}"
106
- middle_options[:source] = join_model.left_reflection.name
107
- if options.key? :foreign_key
108
- middle_options[:foreign_key] = options[:foreign_key]
84
+ def table_name
85
+ if options[:join_table]
86
+ options[:join_table].to_s
87
+ else
88
+ class_name = options.fetch(:class_name) {
89
+ association_name.to_s.camelize.singularize
90
+ }
91
+ klass = lhs_model.send(:compute_type, class_name.to_s)
92
+ [lhs_model.table_name, klass.table_name].sort.join("\0").gsub(/^(.*[._])(.+)\0\1(.+)/, '\1\2_\3').tr("\0", "_")
93
+ end
109
94
  end
110
- middle_options
111
- end
112
95
 
113
- def belongs_to_options(options)
114
- rhs_options = {}
96
+ def belongs_to_options(options)
97
+ rhs_options = {}
115
98
 
116
- if options.key? :class_name
117
- rhs_options[:foreign_key] = options[:class_name].to_s.foreign_key
118
- rhs_options[:class_name] = options[:class_name]
119
- end
99
+ if options.key? :class_name
100
+ rhs_options[:foreign_key] = options[:class_name].to_s.foreign_key
101
+ rhs_options[:class_name] = options[:class_name]
102
+ end
120
103
 
121
- if options.key? :association_foreign_key
122
- rhs_options[:foreign_key] = options[:association_foreign_key]
123
- end
104
+ if options.key? :association_foreign_key
105
+ rhs_options[:foreign_key] = options[:association_foreign_key]
106
+ end
124
107
 
125
- rhs_options
126
- end
108
+ rhs_options
109
+ end
127
110
  end
128
111
  end
@@ -1,15 +1,23 @@
1
- module ActiveRecord::Associations::Builder
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord::Associations::Builder # :nodoc:
2
4
  class HasMany < CollectionAssociation #:nodoc:
3
- def macro
5
+ def self.macro
4
6
  :has_many
5
7
  end
6
8
 
7
- def valid_options
8
- super + [:primary_key, :dependent, :as, :through, :source, :source_type, :inverse_of, :counter_cache, :join_table, :foreign_type]
9
+ def self.valid_options(options)
10
+ valid = super + [:counter_cache, :join_table, :index_errors, :ensuring_owner_was]
11
+ valid += [:as, :foreign_type] if options[:as]
12
+ valid += [:through, :source, :source_type] if options[:through]
13
+ valid += [:ensuring_owner_was] if options[:dependent] == :destroy_async
14
+ valid
9
15
  end
10
16
 
11
17
  def self.valid_dependent_options
12
- [:destroy, :delete_all, :nullify, :restrict_with_error, :restrict_with_exception]
18
+ [:destroy, :delete_all, :nullify, :restrict_with_error, :restrict_with_exception, :destroy_async]
13
19
  end
20
+
21
+ private_class_method :macro, :valid_options, :valid_dependent_options
14
22
  end
15
23
  end