activerecord 6.1.7 → 7.2.2

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 (333) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +616 -1290
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +31 -31
  5. data/examples/performance.rb +2 -2
  6. data/lib/active_record/aggregations.rb +17 -14
  7. data/lib/active_record/association_relation.rb +2 -12
  8. data/lib/active_record/associations/alias_tracker.rb +25 -19
  9. data/lib/active_record/associations/association.rb +60 -21
  10. data/lib/active_record/associations/association_scope.rb +17 -12
  11. data/lib/active_record/associations/belongs_to_association.rb +37 -11
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -4
  13. data/lib/active_record/associations/builder/association.rb +11 -5
  14. data/lib/active_record/associations/builder/belongs_to.rb +41 -14
  15. data/lib/active_record/associations/builder/collection_association.rb +10 -3
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -7
  17. data/lib/active_record/associations/builder/has_many.rb +4 -4
  18. data/lib/active_record/associations/builder/has_one.rb +4 -4
  19. data/lib/active_record/associations/builder/singular_association.rb +6 -2
  20. data/lib/active_record/associations/collection_association.rb +46 -36
  21. data/lib/active_record/associations/collection_proxy.rb +44 -16
  22. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  23. data/lib/active_record/associations/errors.rb +265 -0
  24. data/lib/active_record/associations/foreign_association.rb +10 -3
  25. data/lib/active_record/associations/has_many_association.rb +29 -19
  26. data/lib/active_record/associations/has_many_through_association.rb +19 -8
  27. data/lib/active_record/associations/has_one_association.rb +20 -10
  28. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  29. data/lib/active_record/associations/join_dependency/join_association.rb +30 -27
  30. data/lib/active_record/associations/join_dependency.rb +28 -20
  31. data/lib/active_record/associations/nested_error.rb +47 -0
  32. data/lib/active_record/associations/preloader/association.rb +212 -53
  33. data/lib/active_record/associations/preloader/batch.rb +48 -0
  34. data/lib/active_record/associations/preloader/branch.rb +153 -0
  35. data/lib/active_record/associations/preloader/through_association.rb +50 -16
  36. data/lib/active_record/associations/preloader.rb +50 -121
  37. data/lib/active_record/associations/singular_association.rb +15 -3
  38. data/lib/active_record/associations/through_association.rb +25 -14
  39. data/lib/active_record/associations.rb +429 -522
  40. data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
  41. data/lib/active_record/attribute_assignment.rb +1 -5
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +24 -2
  43. data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
  44. data/lib/active_record/attribute_methods/dirty.rb +73 -22
  45. data/lib/active_record/attribute_methods/primary_key.rb +47 -27
  46. data/lib/active_record/attribute_methods/query.rb +31 -19
  47. data/lib/active_record/attribute_methods/read.rb +14 -11
  48. data/lib/active_record/attribute_methods/serialization.rb +174 -37
  49. data/lib/active_record/attribute_methods/time_zone_conversion.rb +15 -9
  50. data/lib/active_record/attribute_methods/write.rb +12 -15
  51. data/lib/active_record/attribute_methods.rb +164 -52
  52. data/lib/active_record/attributes.rb +57 -54
  53. data/lib/active_record/autosave_association.rb +74 -57
  54. data/lib/active_record/base.rb +27 -5
  55. data/lib/active_record/callbacks.rb +19 -35
  56. data/lib/active_record/coders/column_serializer.rb +61 -0
  57. data/lib/active_record/coders/json.rb +1 -1
  58. data/lib/active_record/coders/yaml_column.rb +70 -46
  59. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +284 -0
  60. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
  61. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +79 -0
  62. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +325 -604
  63. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -17
  64. data/lib/active_record/connection_adapters/abstract/database_statements.rb +199 -60
  65. data/lib/active_record/connection_adapters/abstract/query_cache.rb +230 -64
  66. data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -131
  67. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
  68. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +21 -20
  69. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +186 -31
  70. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
  71. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +378 -143
  72. data/lib/active_record/connection_adapters/abstract/transaction.rb +361 -76
  73. data/lib/active_record/connection_adapters/abstract_adapter.rb +624 -163
  74. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +348 -165
  75. data/lib/active_record/connection_adapters/column.rb +13 -0
  76. data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
  77. data/lib/active_record/connection_adapters/mysql/database_statements.rb +29 -130
  78. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -55
  79. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
  80. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
  81. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
  82. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +45 -14
  83. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +152 -0
  84. data/lib/active_record/connection_adapters/mysql2_adapter.rb +107 -68
  85. data/lib/active_record/connection_adapters/pool_config.rb +26 -16
  86. data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
  87. data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
  88. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +114 -54
  89. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
  94. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
  96. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +12 -3
  97. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
  100. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
  101. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  102. data/lib/active_record/connection_adapters/postgresql/quoting.rb +137 -104
  103. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +28 -0
  104. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +92 -2
  105. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +173 -3
  106. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -0
  107. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +403 -77
  108. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
  109. data/lib/active_record/connection_adapters/postgresql_adapter.rb +520 -253
  110. data/lib/active_record/connection_adapters/schema_cache.rb +326 -102
  111. data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
  112. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +78 -55
  113. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +68 -54
  114. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
  115. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +20 -0
  116. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
  117. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +66 -22
  118. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +372 -130
  119. data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
  120. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
  121. data/lib/active_record/connection_adapters/trilogy_adapter.rb +229 -0
  122. data/lib/active_record/connection_adapters.rb +130 -6
  123. data/lib/active_record/connection_handling.rb +132 -146
  124. data/lib/active_record/core.rb +310 -253
  125. data/lib/active_record/counter_cache.rb +68 -34
  126. data/lib/active_record/database_configurations/connection_url_resolver.rb +10 -4
  127. data/lib/active_record/database_configurations/database_config.rb +34 -10
  128. data/lib/active_record/database_configurations/hash_config.rb +107 -31
  129. data/lib/active_record/database_configurations/url_config.rb +38 -13
  130. data/lib/active_record/database_configurations.rb +96 -60
  131. data/lib/active_record/delegated_type.rb +90 -20
  132. data/lib/active_record/deprecator.rb +7 -0
  133. data/lib/active_record/destroy_association_async_job.rb +4 -2
  134. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  135. data/lib/active_record/dynamic_matchers.rb +3 -3
  136. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  137. data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
  138. data/lib/active_record/encryption/cipher.rb +53 -0
  139. data/lib/active_record/encryption/config.rb +68 -0
  140. data/lib/active_record/encryption/configurable.rb +60 -0
  141. data/lib/active_record/encryption/context.rb +42 -0
  142. data/lib/active_record/encryption/contexts.rb +76 -0
  143. data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
  144. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  145. data/lib/active_record/encryption/encryptable_record.rb +230 -0
  146. data/lib/active_record/encryption/encrypted_attribute_type.rb +175 -0
  147. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  148. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  149. data/lib/active_record/encryption/encryptor.rb +170 -0
  150. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  151. data/lib/active_record/encryption/errors.rb +15 -0
  152. data/lib/active_record/encryption/extended_deterministic_queries.rb +157 -0
  153. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  154. data/lib/active_record/encryption/key.rb +28 -0
  155. data/lib/active_record/encryption/key_generator.rb +53 -0
  156. data/lib/active_record/encryption/key_provider.rb +46 -0
  157. data/lib/active_record/encryption/message.rb +33 -0
  158. data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
  159. data/lib/active_record/encryption/message_serializer.rb +96 -0
  160. data/lib/active_record/encryption/null_encryptor.rb +25 -0
  161. data/lib/active_record/encryption/properties.rb +76 -0
  162. data/lib/active_record/encryption/read_only_null_encryptor.rb +28 -0
  163. data/lib/active_record/encryption/scheme.rb +100 -0
  164. data/lib/active_record/encryption.rb +58 -0
  165. data/lib/active_record/enum.rb +170 -62
  166. data/lib/active_record/errors.rb +210 -27
  167. data/lib/active_record/explain.rb +21 -12
  168. data/lib/active_record/explain_registry.rb +11 -6
  169. data/lib/active_record/explain_subscriber.rb +1 -1
  170. data/lib/active_record/fixture_set/file.rb +15 -1
  171. data/lib/active_record/fixture_set/model_metadata.rb +14 -4
  172. data/lib/active_record/fixture_set/render_context.rb +2 -0
  173. data/lib/active_record/fixture_set/table_row.rb +70 -14
  174. data/lib/active_record/fixture_set/table_rows.rb +4 -4
  175. data/lib/active_record/fixtures.rb +179 -112
  176. data/lib/active_record/future_result.rb +178 -0
  177. data/lib/active_record/gem_version.rb +4 -4
  178. data/lib/active_record/inheritance.rb +85 -31
  179. data/lib/active_record/insert_all.rb +148 -32
  180. data/lib/active_record/integration.rb +14 -10
  181. data/lib/active_record/internal_metadata.rb +123 -23
  182. data/lib/active_record/legacy_yaml_adapter.rb +2 -39
  183. data/lib/active_record/locking/optimistic.rb +43 -27
  184. data/lib/active_record/locking/pessimistic.rb +15 -6
  185. data/lib/active_record/log_subscriber.rb +41 -29
  186. data/lib/active_record/marshalling.rb +59 -0
  187. data/lib/active_record/message_pack.rb +124 -0
  188. data/lib/active_record/middleware/database_selector/resolver.rb +10 -10
  189. data/lib/active_record/middleware/database_selector.rb +23 -13
  190. data/lib/active_record/middleware/shard_selector.rb +62 -0
  191. data/lib/active_record/migration/command_recorder.rb +113 -16
  192. data/lib/active_record/migration/compatibility.rb +235 -46
  193. data/lib/active_record/migration/default_strategy.rb +22 -0
  194. data/lib/active_record/migration/execution_strategy.rb +19 -0
  195. data/lib/active_record/migration/join_table.rb +1 -1
  196. data/lib/active_record/migration/pending_migration_connection.rb +21 -0
  197. data/lib/active_record/migration.rb +374 -177
  198. data/lib/active_record/model_schema.rb +145 -158
  199. data/lib/active_record/nested_attributes.rb +61 -23
  200. data/lib/active_record/no_touching.rb +3 -3
  201. data/lib/active_record/normalization.rb +163 -0
  202. data/lib/active_record/persistence.rb +282 -283
  203. data/lib/active_record/promise.rb +84 -0
  204. data/lib/active_record/query_cache.rb +18 -25
  205. data/lib/active_record/query_logs.rb +189 -0
  206. data/lib/active_record/query_logs_formatter.rb +41 -0
  207. data/lib/active_record/querying.rb +44 -9
  208. data/lib/active_record/railtie.rb +229 -71
  209. data/lib/active_record/railties/controller_runtime.rb +25 -11
  210. data/lib/active_record/railties/databases.rake +189 -256
  211. data/lib/active_record/railties/job_runtime.rb +23 -0
  212. data/lib/active_record/readonly_attributes.rb +41 -3
  213. data/lib/active_record/reflection.rb +332 -103
  214. data/lib/active_record/relation/batches/batch_enumerator.rb +38 -9
  215. data/lib/active_record/relation/batches.rb +200 -65
  216. data/lib/active_record/relation/calculations.rb +301 -112
  217. data/lib/active_record/relation/delegation.rb +33 -22
  218. data/lib/active_record/relation/finder_methods.rb +123 -52
  219. data/lib/active_record/relation/merger.rb +26 -19
  220. data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
  221. data/lib/active_record/relation/predicate_builder/association_query_value.rb +38 -4
  222. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -7
  223. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  224. data/lib/active_record/relation/predicate_builder.rb +29 -22
  225. data/lib/active_record/relation/query_attribute.rb +30 -12
  226. data/lib/active_record/relation/query_methods.rb +870 -163
  227. data/lib/active_record/relation/record_fetch_warning.rb +10 -9
  228. data/lib/active_record/relation/spawn_methods.rb +7 -6
  229. data/lib/active_record/relation/where_clause.rb +15 -36
  230. data/lib/active_record/relation.rb +736 -145
  231. data/lib/active_record/result.rb +67 -54
  232. data/lib/active_record/runtime_registry.rb +71 -13
  233. data/lib/active_record/sanitization.rb +84 -34
  234. data/lib/active_record/schema.rb +39 -23
  235. data/lib/active_record/schema_dumper.rb +90 -31
  236. data/lib/active_record/schema_migration.rb +74 -23
  237. data/lib/active_record/scoping/default.rb +72 -15
  238. data/lib/active_record/scoping/named.rb +6 -13
  239. data/lib/active_record/scoping.rb +65 -34
  240. data/lib/active_record/secure_password.rb +60 -0
  241. data/lib/active_record/secure_token.rb +21 -3
  242. data/lib/active_record/serialization.rb +6 -1
  243. data/lib/active_record/signed_id.rb +30 -9
  244. data/lib/active_record/statement_cache.rb +7 -7
  245. data/lib/active_record/store.rb +10 -10
  246. data/lib/active_record/suppressor.rb +13 -15
  247. data/lib/active_record/table_metadata.rb +7 -3
  248. data/lib/active_record/tasks/database_tasks.rb +288 -149
  249. data/lib/active_record/tasks/mysql_database_tasks.rb +16 -7
  250. data/lib/active_record/tasks/postgresql_database_tasks.rb +35 -26
  251. data/lib/active_record/tasks/sqlite_database_tasks.rb +16 -7
  252. data/lib/active_record/test_databases.rb +1 -1
  253. data/lib/active_record/test_fixtures.rb +173 -155
  254. data/lib/active_record/testing/query_assertions.rb +121 -0
  255. data/lib/active_record/timestamp.rb +32 -19
  256. data/lib/active_record/token_for.rb +123 -0
  257. data/lib/active_record/touch_later.rb +12 -7
  258. data/lib/active_record/transaction.rb +132 -0
  259. data/lib/active_record/transactions.rb +118 -41
  260. data/lib/active_record/translation.rb +3 -5
  261. data/lib/active_record/type/adapter_specific_registry.rb +32 -14
  262. data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
  263. data/lib/active_record/type/internal/timezone.rb +7 -2
  264. data/lib/active_record/type/serialized.rb +9 -7
  265. data/lib/active_record/type/time.rb +4 -0
  266. data/lib/active_record/type/type_map.rb +17 -20
  267. data/lib/active_record/type.rb +1 -2
  268. data/lib/active_record/type_caster/connection.rb +4 -4
  269. data/lib/active_record/validations/absence.rb +1 -1
  270. data/lib/active_record/validations/associated.rb +13 -7
  271. data/lib/active_record/validations/numericality.rb +5 -4
  272. data/lib/active_record/validations/presence.rb +5 -28
  273. data/lib/active_record/validations/uniqueness.rb +65 -15
  274. data/lib/active_record/validations.rb +12 -5
  275. data/lib/active_record/version.rb +1 -1
  276. data/lib/active_record.rb +444 -32
  277. data/lib/arel/alias_predication.rb +1 -1
  278. data/lib/arel/attributes/attribute.rb +0 -8
  279. data/lib/arel/collectors/bind.rb +2 -0
  280. data/lib/arel/collectors/composite.rb +7 -0
  281. data/lib/arel/collectors/sql_string.rb +1 -1
  282. data/lib/arel/collectors/substitute_binds.rb +1 -1
  283. data/lib/arel/crud.rb +28 -22
  284. data/lib/arel/delete_manager.rb +18 -4
  285. data/lib/arel/errors.rb +10 -0
  286. data/lib/arel/factory_methods.rb +4 -0
  287. data/lib/arel/filter_predications.rb +9 -0
  288. data/lib/arel/insert_manager.rb +2 -3
  289. data/lib/arel/nodes/binary.rb +6 -7
  290. data/lib/arel/nodes/bound_sql_literal.rb +65 -0
  291. data/lib/arel/nodes/casted.rb +1 -1
  292. data/lib/arel/nodes/cte.rb +36 -0
  293. data/lib/arel/nodes/delete_statement.rb +12 -13
  294. data/lib/arel/nodes/filter.rb +10 -0
  295. data/lib/arel/nodes/fragments.rb +35 -0
  296. data/lib/arel/nodes/function.rb +1 -0
  297. data/lib/arel/nodes/homogeneous_in.rb +1 -9
  298. data/lib/arel/nodes/insert_statement.rb +2 -2
  299. data/lib/arel/nodes/leading_join.rb +8 -0
  300. data/lib/arel/nodes/{and.rb → nary.rb} +9 -2
  301. data/lib/arel/nodes/node.rb +115 -5
  302. data/lib/arel/nodes/select_core.rb +2 -2
  303. data/lib/arel/nodes/select_statement.rb +2 -2
  304. data/lib/arel/nodes/sql_literal.rb +13 -0
  305. data/lib/arel/nodes/table_alias.rb +4 -0
  306. data/lib/arel/nodes/update_statement.rb +8 -3
  307. data/lib/arel/nodes.rb +7 -2
  308. data/lib/arel/predications.rb +14 -4
  309. data/lib/arel/select_manager.rb +11 -5
  310. data/lib/arel/table.rb +9 -6
  311. data/lib/arel/tree_manager.rb +8 -15
  312. data/lib/arel/update_manager.rb +20 -5
  313. data/lib/arel/visitors/dot.rb +81 -90
  314. data/lib/arel/visitors/mysql.rb +23 -5
  315. data/lib/arel/visitors/postgresql.rb +1 -22
  316. data/lib/arel/visitors/sqlite.rb +25 -0
  317. data/lib/arel/visitors/to_sql.rb +170 -36
  318. data/lib/arel/visitors/visitor.rb +2 -2
  319. data/lib/arel.rb +23 -4
  320. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  321. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  322. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
  323. data/lib/rails/generators/active_record/migration.rb +3 -1
  324. data/lib/rails/generators/active_record/model/USAGE +113 -0
  325. data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
  326. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
  327. data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
  328. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  329. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  330. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  331. metadata +103 -17
  332. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
  333. data/lib/active_record/null_relation.rb +0 -67
@@ -1,265 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/enumerable"
4
- require "active_support/core_ext/string/conversions"
5
-
6
3
  module ActiveRecord
7
- class AssociationNotFoundError < ConfigurationError #:nodoc:
8
- attr_reader :record, :association_name
9
- def initialize(record = nil, association_name = nil)
10
- @record = record
11
- @association_name = association_name
12
- if record && association_name
13
- super("Association named '#{association_name}' was not found on #{record.class.name}; perhaps you misspelled it?")
14
- else
15
- super("Association was not found.")
16
- end
17
- end
18
-
19
- class Correction
20
- def initialize(error)
21
- @error = error
22
- end
23
-
24
- def corrections
25
- if @error.association_name
26
- maybe_these = @error.record.class.reflections.keys
27
-
28
- maybe_these.sort_by { |n|
29
- DidYouMean::Jaro.distance(@error.association_name.to_s, n)
30
- }.reverse.first(4)
31
- else
32
- []
33
- end
34
- end
35
- end
36
-
37
- # We may not have DYM, and DYM might not let us register error handlers
38
- if defined?(DidYouMean) && DidYouMean.respond_to?(:correct_error)
39
- DidYouMean.correct_error(self, Correction)
40
- end
41
- end
42
-
43
- class InverseOfAssociationNotFoundError < ActiveRecordError #:nodoc:
44
- attr_reader :reflection, :associated_class
45
- def initialize(reflection = nil, associated_class = nil)
46
- if reflection
47
- @reflection = reflection
48
- @associated_class = associated_class.nil? ? reflection.klass : associated_class
49
- super("Could not find the inverse association for #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{associated_class.nil? ? reflection.class_name : associated_class.name})")
50
- else
51
- super("Could not find the inverse association.")
52
- end
53
- end
54
-
55
- class Correction
56
- def initialize(error)
57
- @error = error
58
- end
59
-
60
- def corrections
61
- if @error.reflection && @error.associated_class
62
- maybe_these = @error.associated_class.reflections.keys
63
-
64
- maybe_these.sort_by { |n|
65
- DidYouMean::Jaro.distance(@error.reflection.options[:inverse_of].to_s, n)
66
- }.reverse.first(4)
67
- else
68
- []
69
- end
70
- end
71
- end
72
-
73
- # We may not have DYM, and DYM might not let us register error handlers
74
- if defined?(DidYouMean) && DidYouMean.respond_to?(:correct_error)
75
- DidYouMean.correct_error(self, Correction)
76
- end
77
- end
78
-
79
- class HasManyThroughAssociationNotFoundError < ActiveRecordError #:nodoc:
80
- attr_reader :owner_class, :reflection
81
-
82
- def initialize(owner_class = nil, reflection = nil)
83
- if owner_class && reflection
84
- @owner_class = owner_class
85
- @reflection = reflection
86
- super("Could not find the association #{reflection.options[:through].inspect} in model #{owner_class.name}")
87
- else
88
- super("Could not find the association.")
89
- end
90
- end
91
-
92
- class Correction
93
- def initialize(error)
94
- @error = error
95
- end
96
-
97
- def corrections
98
- if @error.reflection && @error.owner_class
99
- maybe_these = @error.owner_class.reflections.keys
100
- maybe_these -= [@error.reflection.name.to_s] # remove failing reflection
101
-
102
- maybe_these.sort_by { |n|
103
- DidYouMean::Jaro.distance(@error.reflection.options[:through].to_s, n)
104
- }.reverse.first(4)
105
- else
106
- []
107
- end
108
- end
109
- end
110
-
111
- # We may not have DYM, and DYM might not let us register error handlers
112
- if defined?(DidYouMean) && DidYouMean.respond_to?(:correct_error)
113
- DidYouMean.correct_error(self, Correction)
114
- end
115
- end
116
-
117
- class HasManyThroughAssociationPolymorphicSourceError < ActiveRecordError #:nodoc:
118
- def initialize(owner_class_name = nil, reflection = nil, source_reflection = nil)
119
- if owner_class_name && reflection && source_reflection
120
- super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' on the polymorphic object '#{source_reflection.class_name}##{source_reflection.name}' without 'source_type'. Try adding 'source_type: \"#{reflection.name.to_s.classify}\"' to 'has_many :through' definition.")
121
- else
122
- super("Cannot have a has_many :through association.")
123
- end
124
- end
125
- end
126
-
127
- class HasManyThroughAssociationPolymorphicThroughError < ActiveRecordError #:nodoc:
128
- def initialize(owner_class_name = nil, reflection = nil)
129
- if owner_class_name && reflection
130
- super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' which goes through the polymorphic association '#{owner_class_name}##{reflection.through_reflection.name}'.")
131
- else
132
- super("Cannot have a has_many :through association.")
133
- end
134
- end
135
- end
136
-
137
- class HasManyThroughAssociationPointlessSourceTypeError < ActiveRecordError #:nodoc:
138
- def initialize(owner_class_name = nil, reflection = nil, source_reflection = nil)
139
- if owner_class_name && reflection && source_reflection
140
- super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' with a :source_type option if the '#{reflection.through_reflection.class_name}##{source_reflection.name}' is not polymorphic. Try removing :source_type on your association.")
141
- else
142
- super("Cannot have a has_many :through association.")
143
- end
144
- end
145
- end
146
-
147
- class HasOneThroughCantAssociateThroughCollection < ActiveRecordError #:nodoc:
148
- def initialize(owner_class_name = nil, reflection = nil, through_reflection = nil)
149
- if owner_class_name && reflection && through_reflection
150
- super("Cannot have a has_one :through association '#{owner_class_name}##{reflection.name}' where the :through association '#{owner_class_name}##{through_reflection.name}' is a collection. Specify a has_one or belongs_to association in the :through option instead.")
151
- else
152
- super("Cannot have a has_one :through association.")
153
- end
154
- end
155
- end
156
-
157
- class HasOneAssociationPolymorphicThroughError < ActiveRecordError #:nodoc:
158
- def initialize(owner_class_name = nil, reflection = nil)
159
- if owner_class_name && reflection
160
- super("Cannot have a has_one :through association '#{owner_class_name}##{reflection.name}' which goes through the polymorphic association '#{owner_class_name}##{reflection.through_reflection.name}'.")
161
- else
162
- super("Cannot have a has_one :through association.")
163
- end
164
- end
165
- end
166
-
167
- class HasManyThroughSourceAssociationNotFoundError < ActiveRecordError #:nodoc:
168
- def initialize(reflection = nil)
169
- if reflection
170
- through_reflection = reflection.through_reflection
171
- source_reflection_names = reflection.source_reflection_names
172
- source_associations = reflection.through_reflection.klass._reflections.keys
173
- super("Could not find the source association(s) #{source_reflection_names.collect(&:inspect).to_sentence(two_words_connector: ' or ', last_word_connector: ', or ')} in model #{through_reflection.klass}. Try 'has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}, :source => <name>'. Is it one of #{source_associations.to_sentence(two_words_connector: ' or ', last_word_connector: ', or ')}?")
174
- else
175
- super("Could not find the source association(s).")
176
- end
177
- end
178
- end
179
-
180
- class HasManyThroughOrderError < ActiveRecordError #:nodoc:
181
- def initialize(owner_class_name = nil, reflection = nil, through_reflection = nil)
182
- if owner_class_name && reflection && through_reflection
183
- super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' which goes through '#{owner_class_name}##{through_reflection.name}' before the through association is defined.")
184
- else
185
- super("Cannot have a has_many :through association before the through association is defined.")
186
- end
187
- end
188
- end
189
-
190
- class ThroughCantAssociateThroughHasOneOrManyReflection < ActiveRecordError #:nodoc:
191
- def initialize(owner = nil, reflection = nil)
192
- if owner && reflection
193
- super("Cannot modify association '#{owner.class.name}##{reflection.name}' because the source reflection class '#{reflection.source_reflection.class_name}' is associated to '#{reflection.through_reflection.class_name}' via :#{reflection.source_reflection.macro}.")
194
- else
195
- super("Cannot modify association.")
196
- end
197
- end
198
- end
199
-
200
- class AmbiguousSourceReflectionForThroughAssociation < ActiveRecordError # :nodoc:
201
- def initialize(klass, macro, association_name, options, possible_sources)
202
- example_options = options.dup
203
- example_options[:source] = possible_sources.first
204
-
205
- super("Ambiguous source reflection for through association. Please " \
206
- "specify a :source directive on your declaration like:\n" \
207
- "\n" \
208
- " class #{klass} < ActiveRecord::Base\n" \
209
- " #{macro} :#{association_name}, #{example_options}\n" \
210
- " end"
211
- )
212
- end
213
- end
214
-
215
- class HasManyThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection #:nodoc:
216
- end
217
-
218
- class HasOneThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection #:nodoc:
219
- end
220
-
221
- class ThroughNestedAssociationsAreReadonly < ActiveRecordError #:nodoc:
222
- def initialize(owner = nil, reflection = nil)
223
- if owner && reflection
224
- super("Cannot modify association '#{owner.class.name}##{reflection.name}' because it goes through more than one other association.")
225
- else
226
- super("Through nested associations are read-only.")
227
- end
228
- end
229
- end
230
-
231
- class HasManyThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly #:nodoc:
232
- end
233
-
234
- class HasOneThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly #:nodoc:
235
- end
236
-
237
- # This error is raised when trying to eager load a polymorphic association using a JOIN.
238
- # Eager loading polymorphic associations is only possible with
239
- # {ActiveRecord::Relation#preload}[rdoc-ref:QueryMethods#preload].
240
- class EagerLoadPolymorphicError < ActiveRecordError
241
- def initialize(reflection = nil)
242
- if reflection
243
- super("Cannot eagerly load the polymorphic association #{reflection.name.inspect}")
244
- else
245
- super("Eager load polymorphic error.")
246
- end
247
- end
248
- end
249
-
250
- # This error is raised when trying to destroy a parent instance in N:1 or 1:1 associations
251
- # (has_many, has_one) when there is at least 1 child associated instance.
252
- # ex: if @project.tasks.size > 0, DeleteRestrictionError will be raised when trying to destroy @project
253
- class DeleteRestrictionError < ActiveRecordError #:nodoc:
254
- def initialize(name = nil)
255
- if name
256
- super("Cannot delete record because of dependent #{name}")
257
- else
258
- super("Delete restriction error.")
259
- end
260
- end
261
- end
262
-
263
4
  # See ActiveRecord::Associations::ClassMethods for documentation.
264
5
  module Associations # :nodoc:
265
6
  extend ActiveSupport::Autoload
@@ -274,7 +15,7 @@ module ActiveRecord
274
15
  autoload :CollectionProxy
275
16
  autoload :ThroughAssociation
276
17
 
277
- module Builder #:nodoc:
18
+ module Builder # :nodoc:
278
19
  autoload :Association, "active_record/associations/builder/association"
279
20
  autoload :SingularAssociation, "active_record/associations/builder/singular_association"
280
21
  autoload :CollectionAssociation, "active_record/associations/builder/collection_association"
@@ -296,16 +37,18 @@ module ActiveRecord
296
37
  autoload :Preloader
297
38
  autoload :JoinDependency
298
39
  autoload :AssociationScope
40
+ autoload :DisableJoinsAssociationScope
299
41
  autoload :AliasTracker
300
42
  end
301
43
 
302
44
  def self.eager_load!
303
45
  super
304
46
  Preloader.eager_load!
47
+ JoinDependency.eager_load!
305
48
  end
306
49
 
307
50
  # Returns the association instance for the given name, instantiating it if it doesn't already exist
308
- def association(name) #:nodoc:
51
+ def association(name) # :nodoc:
309
52
  association = association_instance_get(name)
310
53
 
311
54
  if association.nil?
@@ -328,20 +71,10 @@ module ActiveRecord
328
71
  super
329
72
  end
330
73
 
331
- def reload(*) # :nodoc:
332
- clear_association_cache
333
- super
334
- end
335
-
336
74
  private
337
- # Clears out the association cache.
338
- def clear_association_cache
339
- @association_cache.clear if persisted?
340
- end
341
-
342
75
  def init_internals
343
- @association_cache = {}
344
76
  super
77
+ @association_cache = {}
345
78
  end
346
79
 
347
80
  # Returns the specified association instance if it exists, +nil+ otherwise.
@@ -354,6 +87,8 @@ module ActiveRecord
354
87
  @association_cache[name] = association
355
88
  end
356
89
 
90
+ # = Active Record \Associations
91
+ #
357
92
  # \Associations are a set of macro-like class methods for tying objects together through
358
93
  # foreign keys. They express relationships like "Project has one Project Manager"
359
94
  # or "Project belongs to a Portfolio". Each macro adds a number of methods to the
@@ -370,23 +105,42 @@ module ActiveRecord
370
105
  #
371
106
  # The project class now has the following methods (and more) to ease the traversal and
372
107
  # manipulation of its relationships:
373
- # * <tt>Project#portfolio</tt>, <tt>Project#portfolio=(portfolio)</tt>, <tt>Project#reload_portfolio</tt>
374
- # * <tt>Project#project_manager</tt>, <tt>Project#project_manager=(project_manager)</tt>, <tt>Project#reload_project_manager</tt>
375
- # * <tt>Project#milestones.empty?</tt>, <tt>Project#milestones.size</tt>, <tt>Project#milestones</tt>, <tt>Project#milestones<<(milestone)</tt>,
376
- # <tt>Project#milestones.delete(milestone)</tt>, <tt>Project#milestones.destroy(milestone)</tt>, <tt>Project#milestones.find(milestone_id)</tt>,
377
- # <tt>Project#milestones.build</tt>, <tt>Project#milestones.create</tt>
378
- # * <tt>Project#categories.empty?</tt>, <tt>Project#categories.size</tt>, <tt>Project#categories</tt>, <tt>Project#categories<<(category1)</tt>,
379
- # <tt>Project#categories.delete(category1)</tt>, <tt>Project#categories.destroy(category1)</tt>
108
+ #
109
+ # project = Project.first
110
+ # project.portfolio
111
+ # project.portfolio = Portfolio.first
112
+ # project.reload_portfolio
113
+ #
114
+ # project.project_manager
115
+ # project.project_manager = ProjectManager.first
116
+ # project.reload_project_manager
117
+ #
118
+ # project.milestones.empty?
119
+ # project.milestones.size
120
+ # project.milestones
121
+ # project.milestones << Milestone.first
122
+ # project.milestones.delete(Milestone.first)
123
+ # project.milestones.destroy(Milestone.first)
124
+ # project.milestones.find(Milestone.first.id)
125
+ # project.milestones.build
126
+ # project.milestones.create
127
+ #
128
+ # project.categories.empty?
129
+ # project.categories.size
130
+ # project.categories
131
+ # project.categories << Category.first
132
+ # project.categories.delete(category1)
133
+ # project.categories.destroy(category1)
380
134
  #
381
135
  # === A word of warning
382
136
  #
383
137
  # Don't create associations that have the same name as {instance methods}[rdoc-ref:ActiveRecord::Core] of
384
- # <tt>ActiveRecord::Base</tt>. Since the association adds a method with that name to
385
- # its model, using an association with the same name as one provided by <tt>ActiveRecord::Base</tt> will override the method inherited through <tt>ActiveRecord::Base</tt> and will break things.
386
- # For instance, +attributes+ and +connection+ would be bad choices for association names, because those names already exist in the list of <tt>ActiveRecord::Base</tt> instance methods.
138
+ # +ActiveRecord::Base+. Since the association adds a method with that name to
139
+ # its model, using an association with the same name as one provided by +ActiveRecord::Base+ will override the method inherited through +ActiveRecord::Base+ and will break things.
140
+ # For instance, +attributes+ and +connection+ would be bad choices for association names, because those names already exist in the list of +ActiveRecord::Base+ instance methods.
387
141
  #
388
142
  # == Auto-generated methods
389
- # See also Instance Public methods below for more details.
143
+ # See also "Instance Public methods" below ( from #belongs_to ) for more details.
390
144
  #
391
145
  # === Singular associations (one-to-one)
392
146
  # | | belongs_to |
@@ -398,6 +152,8 @@ module ActiveRecord
398
152
  # create_other(attributes={}) | X | | X
399
153
  # create_other!(attributes={}) | X | | X
400
154
  # reload_other | X | X | X
155
+ # other_changed? | X | X |
156
+ # other_previously_changed? | X | X |
401
157
  #
402
158
  # === Collection associations (one-to-many / many-to-many)
403
159
  # | | | has_many
@@ -451,7 +207,7 @@ module ActiveRecord
451
207
  #
452
208
  # == Cardinality and associations
453
209
  #
454
- # Active Record associations can be used to describe one-to-one, one-to-many and many-to-many
210
+ # Active Record associations can be used to describe one-to-one, one-to-many, and many-to-many
455
211
  # relationships between models. Each model uses an association to describe its role in
456
212
  # the relation. The #belongs_to association is always used in the model that has
457
213
  # the foreign key.
@@ -605,8 +361,11 @@ module ActiveRecord
605
361
  # has_many :birthday_events, ->(user) { where(starts_on: user.birthday) }, class_name: 'Event'
606
362
  # end
607
363
  #
608
- # Note: Joining, eager loading and preloading of these associations is not possible.
609
- # These operations happen before instance creation and the scope will be called with a +nil+ argument.
364
+ # Note: Joining or eager loading such associations is not possible because
365
+ # those operations happen before instance creation. Such associations
366
+ # _can_ be preloaded, but doing so will perform N+1 queries because there
367
+ # will be a different scope for each record (similar to preloading
368
+ # polymorphic scopes).
610
369
  #
611
370
  # == Association callbacks
612
371
  #
@@ -614,22 +373,31 @@ module ActiveRecord
614
373
  # you can also define callbacks that get triggered when you add an object to or remove an
615
374
  # object from an association collection.
616
375
  #
617
- # class Project
618
- # has_and_belongs_to_many :developers, after_add: :evaluate_velocity
376
+ # class Firm < ActiveRecord::Base
377
+ # has_many :clients,
378
+ # dependent: :destroy,
379
+ # after_add: :congratulate_client,
380
+ # after_remove: :log_after_remove
619
381
  #
620
- # def evaluate_velocity(developer)
621
- # ...
382
+ # def congratulate_client(record)
383
+ # # ...
384
+ # end
385
+ #
386
+ # def log_after_remove(record)
387
+ # # ...
622
388
  # end
623
389
  # end
624
390
  #
625
391
  # It's possible to stack callbacks by passing them as an array. Example:
626
392
  #
627
- # class Project
628
- # has_and_belongs_to_many :developers,
629
- # after_add: [:evaluate_velocity, Proc.new { |p, d| p.shipping_date = Time.now}]
393
+ # class Firm < ActiveRecord::Base
394
+ # has_many :clients,
395
+ # dependent: :destroy,
396
+ # after_add: [:congratulate_client, -> (firm, record) { firm.log << "after_adding#{record.id}" }],
397
+ # after_remove: :log_after_remove
630
398
  # end
631
399
  #
632
- # Possible callbacks are: +before_add+, +after_add+, +before_remove+ and +after_remove+.
400
+ # Possible callbacks are: +before_add+, +after_add+, +before_remove+, and +after_remove+.
633
401
  #
634
402
  # If any of the +before_add+ callbacks throw an exception, the object will not be
635
403
  # added to the collection.
@@ -637,6 +405,18 @@ module ActiveRecord
637
405
  # Similarly, if any of the +before_remove+ callbacks throw an exception, the object
638
406
  # will not be removed from the collection.
639
407
  #
408
+ # Note: To trigger remove callbacks, you must use +destroy+ / +destroy_all+ methods. For example:
409
+ #
410
+ # * <tt>firm.clients.destroy(client)</tt>
411
+ # * <tt>firm.clients.destroy(*clients)</tt>
412
+ # * <tt>firm.clients.destroy_all</tt>
413
+ #
414
+ # +delete+ / +delete_all+ methods like the following do *not* trigger remove callbacks:
415
+ #
416
+ # * <tt>firm.clients.delete(client)</tt>
417
+ # * <tt>firm.clients.delete(*clients)</tt>
418
+ # * <tt>firm.clients.delete_all</tt>
419
+ #
640
420
  # == Association extensions
641
421
  #
642
422
  # The proxy objects that control the access to associations can be extended through anonymous
@@ -757,7 +537,7 @@ module ActiveRecord
757
537
  # @group.avatars << Avatar.new # this would work if User belonged_to Avatar rather than the other way around
758
538
  # @group.avatars.delete(@group.avatars.last) # so would this
759
539
  #
760
- # == Setting Inverses
540
+ # === Setting Inverses
761
541
  #
762
542
  # If you are using a #belongs_to on the join model, it is a good idea to set the
763
543
  # <tt>:inverse_of</tt> option on the #belongs_to, which will mean that the following example
@@ -780,9 +560,10 @@ module ActiveRecord
780
560
  # inverse detection only works on #has_many, #has_one, and
781
561
  # #belongs_to associations.
782
562
  #
783
- # <tt>:foreign_key</tt> and <tt>:through</tt> options on the associations,
784
- # or a custom scope, will also prevent the association's inverse
785
- # from being found automatically.
563
+ # <tt>:foreign_key</tt> and <tt>:through</tt> options on the associations
564
+ # will also prevent the association's inverse from being found automatically,
565
+ # as will a custom scopes in some cases. See further details in the
566
+ # {Active Record Associations guide}[https://guides.rubyonrails.org/association_basics.html#bi-directional-associations].
786
567
  #
787
568
  # The automatic guessing of the inverse association uses a heuristic based
788
569
  # on the name of the class, so it may not work for all associations,
@@ -1007,7 +788,7 @@ module ActiveRecord
1007
788
  # query per addressable type.
1008
789
  # For example, if all the addressables are either of class Person or Company, then a total
1009
790
  # of 3 queries will be executed. The list of addressable types to load is determined on
1010
- # the back of the addresses loaded. This is not supported if Active Record has to fallback
791
+ # the back of the addresses loaded. This is not supported if Active Record has to fall back
1011
792
  # to the previous implementation of eager loading and will raise ActiveRecord::EagerLoadPolymorphicError.
1012
793
  # The reason is that the parent model's type is a column value so its corresponding table
1013
794
  # name cannot be put in the +FROM+/+JOIN+ clauses of that query.
@@ -1020,45 +801,45 @@ module ActiveRecord
1020
801
  # Indexes are appended for any more successive uses of the table name.
1021
802
  #
1022
803
  # Post.joins(:comments)
1023
- # # => SELECT ... FROM posts INNER JOIN comments ON ...
804
+ # # SELECT ... FROM posts INNER JOIN comments ON ...
1024
805
  # Post.joins(:special_comments) # STI
1025
- # # => SELECT ... FROM posts INNER JOIN comments ON ... AND comments.type = 'SpecialComment'
806
+ # # SELECT ... FROM posts INNER JOIN comments ON ... AND comments.type = 'SpecialComment'
1026
807
  # Post.joins(:comments, :special_comments) # special_comments is the reflection name, posts is the parent table name
1027
- # # => SELECT ... FROM posts INNER JOIN comments ON ... INNER JOIN comments special_comments_posts
808
+ # # SELECT ... FROM posts INNER JOIN comments ON ... INNER JOIN comments special_comments_posts
1028
809
  #
1029
810
  # Acts as tree example:
1030
811
  #
1031
812
  # TreeMixin.joins(:children)
1032
- # # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
813
+ # # SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
1033
814
  # TreeMixin.joins(children: :parent)
1034
- # # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
1035
- # INNER JOIN parents_mixins ...
815
+ # # SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
816
+ # # INNER JOIN parents_mixins ...
1036
817
  # TreeMixin.joins(children: {parent: :children})
1037
- # # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
1038
- # INNER JOIN parents_mixins ...
1039
- # INNER JOIN mixins childrens_mixins_2
818
+ # # SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
819
+ # # INNER JOIN parents_mixins ...
820
+ # # INNER JOIN mixins childrens_mixins_2
1040
821
  #
1041
822
  # Has and Belongs to Many join tables use the same idea, but add a <tt>_join</tt> suffix:
1042
823
  #
1043
824
  # Post.joins(:categories)
1044
- # # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
825
+ # # SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
1045
826
  # Post.joins(categories: :posts)
1046
- # # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
1047
- # INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
827
+ # # SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
828
+ # # INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
1048
829
  # Post.joins(categories: {posts: :categories})
1049
- # # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
1050
- # INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
1051
- # INNER JOIN categories_posts categories_posts_join INNER JOIN categories categories_posts_2
830
+ # # SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
831
+ # # INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
832
+ # # INNER JOIN categories_posts categories_posts_join INNER JOIN categories categories_posts_2
1052
833
  #
1053
834
  # If you wish to specify your own custom joins using ActiveRecord::QueryMethods#joins method, those table
1054
835
  # names will take precedence over the eager associations:
1055
836
  #
1056
837
  # Post.joins(:comments).joins("inner join comments ...")
1057
- # # => SELECT ... FROM posts INNER JOIN comments_posts ON ... INNER JOIN comments ...
838
+ # # SELECT ... FROM posts INNER JOIN comments_posts ON ... INNER JOIN comments ...
1058
839
  # Post.joins(:comments, :special_comments).joins("inner join comments ...")
1059
- # # => SELECT ... FROM posts INNER JOIN comments comments_posts ON ...
1060
- # INNER JOIN comments special_comments_posts ...
1061
- # INNER JOIN comments ...
840
+ # # SELECT ... FROM posts INNER JOIN comments comments_posts ON ...
841
+ # # INNER JOIN comments special_comments_posts ...
842
+ # # INNER JOIN comments ...
1062
843
  #
1063
844
  # Table aliases are automatically truncated according to the maximum length of table identifiers
1064
845
  # according to the specific database.
@@ -1139,7 +920,8 @@ module ActiveRecord
1139
920
  # belongs_to :dungeon, inverse_of: :evil_wizard
1140
921
  # end
1141
922
  #
1142
- # For more information, see the documentation for the +:inverse_of+ option.
923
+ # For more information, see the documentation for the +:inverse_of+ option and the
924
+ # {Active Record Associations guide}[https://guides.rubyonrails.org/association_basics.html#bi-directional-associations].
1143
925
  #
1144
926
  # == Deleting from associations
1145
927
  #
@@ -1161,7 +943,7 @@ module ActiveRecord
1161
943
  # specific association types. When no option is given, the behavior is to do nothing
1162
944
  # with the associated records when destroying a record.
1163
945
  #
1164
- # Note that <tt>:dependent</tt> is implemented using Rails' callback
946
+ # Note that <tt>:dependent</tt> is implemented using \Rails' callback
1165
947
  # system, which works by processing callbacks in order. Therefore, other
1166
948
  # callbacks declared either before or after the <tt>:dependent</tt> option
1167
949
  # can affect what it does.
@@ -1232,15 +1014,15 @@ module ActiveRecord
1232
1014
  # +collection+ is a placeholder for the symbol passed as the +name+ argument, so
1233
1015
  # <tt>has_many :clients</tt> would add among others <tt>clients.empty?</tt>.
1234
1016
  #
1235
- # [collection]
1017
+ # [<tt>collection</tt>]
1236
1018
  # Returns a Relation of all the associated objects.
1237
1019
  # An empty Relation is returned if none are found.
1238
- # [collection<<(object, ...)]
1020
+ # [<tt>collection<<(object, ...)</tt>]
1239
1021
  # Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
1240
1022
  # Note that this operation instantly fires update SQL without waiting for the save or update call on the
1241
1023
  # parent object, unless the parent object is a new record.
1242
1024
  # This will also run validations and callbacks of associated object(s).
1243
- # [collection.delete(object, ...)]
1025
+ # [<tt>collection.delete(object, ...)</tt>]
1244
1026
  # Removes one or more objects from the collection by setting their foreign keys to +NULL+.
1245
1027
  # Objects will be in addition destroyed if they're associated with <tt>dependent: :destroy</tt>,
1246
1028
  # and deleted if they're associated with <tt>dependent: :delete_all</tt>.
@@ -1248,75 +1030,84 @@ module ActiveRecord
1248
1030
  # If the <tt>:through</tt> option is used, then the join records are deleted (rather than
1249
1031
  # nullified) by default, but you can specify <tt>dependent: :destroy</tt> or
1250
1032
  # <tt>dependent: :nullify</tt> to override this.
1251
- # [collection.destroy(object, ...)]
1033
+ # [<tt>collection.destroy(object, ...)</tt>]
1252
1034
  # Removes one or more objects from the collection by running <tt>destroy</tt> on
1253
1035
  # each record, regardless of any dependent option, ensuring callbacks are run.
1254
1036
  #
1255
1037
  # If the <tt>:through</tt> option is used, then the join records are destroyed
1256
1038
  # instead, not the objects themselves.
1257
- # [collection=objects]
1039
+ # [<tt>collection=objects</tt>]
1258
1040
  # Replaces the collections content by deleting and adding objects as appropriate. If the <tt>:through</tt>
1259
1041
  # option is true callbacks in the join models are triggered except destroy callbacks, since deletion is
1260
1042
  # direct by default. You can specify <tt>dependent: :destroy</tt> or
1261
1043
  # <tt>dependent: :nullify</tt> to override this.
1262
- # [collection_singular_ids]
1044
+ # [<tt>collection_singular_ids</tt>]
1263
1045
  # Returns an array of the associated objects' ids
1264
- # [collection_singular_ids=ids]
1046
+ # [<tt>collection_singular_ids=ids</tt>]
1265
1047
  # Replace the collection with the objects identified by the primary keys in +ids+. This
1266
1048
  # method loads the models and calls <tt>collection=</tt>. See above.
1267
- # [collection.clear]
1049
+ # [<tt>collection.clear</tt>]
1268
1050
  # Removes every object from the collection. This destroys the associated objects if they
1269
1051
  # are associated with <tt>dependent: :destroy</tt>, deletes them directly from the
1270
1052
  # database if <tt>dependent: :delete_all</tt>, otherwise sets their foreign keys to +NULL+.
1271
1053
  # If the <tt>:through</tt> option is true no destroy callbacks are invoked on the join models.
1272
1054
  # Join models are directly deleted.
1273
- # [collection.empty?]
1055
+ # [<tt>collection.empty?</tt>]
1274
1056
  # Returns +true+ if there are no associated objects.
1275
- # [collection.size]
1057
+ # [<tt>collection.size</tt>]
1276
1058
  # Returns the number of associated objects.
1277
- # [collection.find(...)]
1059
+ # [<tt>collection.find(...)</tt>]
1278
1060
  # Finds an associated object according to the same rules as ActiveRecord::FinderMethods#find.
1279
- # [collection.exists?(...)]
1061
+ # [<tt>collection.exists?(...)</tt>]
1280
1062
  # Checks whether an associated object with the given conditions exists.
1281
1063
  # Uses the same rules as ActiveRecord::FinderMethods#exists?.
1282
- # [collection.build(attributes = {}, ...)]
1064
+ # [<tt>collection.build(attributes = {}, ...)</tt>]
1283
1065
  # Returns one or more new objects of the collection type that have been instantiated
1284
1066
  # with +attributes+ and linked to this object through a foreign key, but have not yet
1285
1067
  # been saved.
1286
- # [collection.create(attributes = {})]
1068
+ # [<tt>collection.create(attributes = {})</tt>]
1287
1069
  # Returns a new object of the collection type that has been instantiated
1288
1070
  # with +attributes+, linked to this object through a foreign key, and that has already
1289
1071
  # been saved (if it passed the validation). *Note*: This only works if the base model
1290
1072
  # already exists in the DB, not if it is a new (unsaved) record!
1291
- # [collection.create!(attributes = {})]
1073
+ # [<tt>collection.create!(attributes = {})</tt>]
1292
1074
  # Does the same as <tt>collection.create</tt>, but raises ActiveRecord::RecordInvalid
1293
1075
  # if the record is invalid.
1294
- # [collection.reload]
1076
+ # [<tt>collection.reload</tt>]
1295
1077
  # Returns a Relation of all of the associated objects, forcing a database read.
1296
1078
  # An empty Relation is returned if none are found.
1297
1079
  #
1298
- # === Example
1299
- #
1300
- # A <tt>Firm</tt> class declares <tt>has_many :clients</tt>, which will add:
1301
- # * <tt>Firm#clients</tt> (similar to <tt>Client.where(firm_id: id)</tt>)
1302
- # * <tt>Firm#clients<<</tt>
1303
- # * <tt>Firm#clients.delete</tt>
1304
- # * <tt>Firm#clients.destroy</tt>
1305
- # * <tt>Firm#clients=</tt>
1306
- # * <tt>Firm#client_ids</tt>
1307
- # * <tt>Firm#client_ids=</tt>
1308
- # * <tt>Firm#clients.clear</tt>
1309
- # * <tt>Firm#clients.empty?</tt> (similar to <tt>firm.clients.size == 0</tt>)
1310
- # * <tt>Firm#clients.size</tt> (similar to <tt>Client.count "firm_id = #{id}"</tt>)
1311
- # * <tt>Firm#clients.find</tt> (similar to <tt>Client.where(firm_id: id).find(id)</tt>)
1312
- # * <tt>Firm#clients.exists?(name: 'ACME')</tt> (similar to <tt>Client.exists?(name: 'ACME', firm_id: firm.id)</tt>)
1313
- # * <tt>Firm#clients.build</tt> (similar to <tt>Client.new(firm_id: id)</tt>)
1314
- # * <tt>Firm#clients.create</tt> (similar to <tt>c = Client.new(firm_id: id); c.save; c</tt>)
1315
- # * <tt>Firm#clients.create!</tt> (similar to <tt>c = Client.new(firm_id: id); c.save!</tt>)
1316
- # * <tt>Firm#clients.reload</tt>
1080
+ # ==== Example
1081
+ #
1082
+ # class Firm < ActiveRecord::Base
1083
+ # has_many :clients
1084
+ # end
1085
+ #
1086
+ # Declaring <tt>has_many :clients</tt> adds the following methods (and more):
1087
+ #
1088
+ # firm = Firm.find(2)
1089
+ # client = Client.find(6)
1090
+ #
1091
+ # firm.clients # similar to Client.where(firm_id: 2)
1092
+ # firm.clients << client
1093
+ # firm.clients.delete(client)
1094
+ # firm.clients.destroy(client)
1095
+ # firm.clients = [client]
1096
+ # firm.client_ids
1097
+ # firm.client_ids = [6]
1098
+ # firm.clients.clear
1099
+ # firm.clients.empty? # similar to firm.clients.size == 0
1100
+ # firm.clients.size # similar to Client.count "firm_id = 2"
1101
+ # firm.clients.find # similar to Client.where(firm_id: 2).find(6)
1102
+ # firm.clients.exists?(name: 'ACME') # similar to Client.exists?(name: 'ACME', firm_id: 2)
1103
+ # firm.clients.build # similar to Client.new(firm_id: 2)
1104
+ # firm.clients.create # similar to Client.create(firm_id: 2)
1105
+ # firm.clients.create! # similar to Client.create!(firm_id: 2)
1106
+ # firm.clients.reload
1107
+ #
1317
1108
  # The declaration can also include an +options+ hash to specialize the behavior of the association.
1318
1109
  #
1319
- # === Scopes
1110
+ # ==== Scopes
1320
1111
  #
1321
1112
  # You can pass a second argument +scope+ as a callable (i.e. proc or
1322
1113
  # lambda) to retrieve a specific set of records or customize the generated
@@ -1327,10 +1118,10 @@ module ActiveRecord
1327
1118
  # has_many :employees, -> { joins(:address) }
1328
1119
  # has_many :posts, ->(blog) { where("max_post_length > ?", blog.max_post_length) }
1329
1120
  #
1330
- # === Extensions
1121
+ # ==== Extensions
1331
1122
  #
1332
1123
  # The +extension+ argument allows you to pass a block into a has_many
1333
- # association. This is useful for adding new finders, creators and other
1124
+ # association. This is useful for adding new finders, creators, and other
1334
1125
  # factory-type methods to be used as part of the association.
1335
1126
  #
1336
1127
  # Extension examples:
@@ -1341,31 +1132,31 @@ module ActiveRecord
1341
1132
  # end
1342
1133
  # end
1343
1134
  #
1344
- # === Options
1345
- # [:class_name]
1135
+ # ==== Options
1136
+ # [+:class_name+]
1346
1137
  # Specify the class name of the association. Use it only if that name can't be inferred
1347
1138
  # from the association name. So <tt>has_many :products</tt> will by default be linked
1348
1139
  # to the +Product+ class, but if the real class name is +SpecialProduct+, you'll have to
1349
1140
  # specify it with this option.
1350
- # [:foreign_key]
1141
+ # [+:foreign_key+]
1351
1142
  # Specify the foreign key used for the association. By default this is guessed to be the name
1352
1143
  # of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_many
1353
1144
  # association will use "person_id" as the default <tt>:foreign_key</tt>.
1354
1145
  #
1355
- # If you are going to modify the association (rather than just read from it), then it is
1356
- # a good idea to set the <tt>:inverse_of</tt> option.
1357
- # [:foreign_type]
1146
+ # Setting the <tt>:foreign_key</tt> option prevents automatic detection of the association's
1147
+ # inverse, so it is generally a good idea to set the <tt>:inverse_of</tt> option as well.
1148
+ # [+:foreign_type+]
1358
1149
  # Specify the column used to store the associated object's type, if this is a polymorphic
1359
1150
  # association. By default this is guessed to be the name of the polymorphic association
1360
1151
  # specified on "as" option with a "_type" suffix. So a class that defines a
1361
1152
  # <tt>has_many :tags, as: :taggable</tt> association will use "taggable_type" as the
1362
1153
  # default <tt>:foreign_type</tt>.
1363
- # [:primary_key]
1154
+ # [+:primary_key+]
1364
1155
  # Specify the name of the column to use as the primary key for the association. By default this is +id+.
1365
- # [:dependent]
1156
+ # [+:dependent+]
1366
1157
  # Controls what happens to the associated objects when
1367
1158
  # their owner is destroyed. Note that these are implemented as
1368
- # callbacks, and Rails executes callbacks in order. Therefore, other
1159
+ # callbacks, and \Rails executes callbacks in order. Therefore, other
1369
1160
  # similar callbacks may affect the <tt>:dependent</tt> behavior, and the
1370
1161
  # <tt>:dependent</tt> behavior may affect other callbacks.
1371
1162
  #
@@ -1377,7 +1168,7 @@ module ActiveRecord
1377
1168
  # * <tt>:delete_all</tt> causes all the associated objects to be deleted directly from the database (so callbacks will not be executed).
1378
1169
  # * <tt>:nullify</tt> causes the foreign keys to be set to +NULL+. Polymorphic type will also be nullified
1379
1170
  # on polymorphic associations. Callbacks are not executed.
1380
- # * <tt>:restrict_with_exception</tt> causes an <tt>ActiveRecord::DeleteRestrictionError</tt> exception to be raised if there are any associated records.
1171
+ # * <tt>:restrict_with_exception</tt> causes an ActiveRecord::DeleteRestrictionError exception to be raised if there are any associated records.
1381
1172
  # * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there are any associated objects.
1382
1173
  #
1383
1174
  # If using with the <tt>:through</tt> option, the association on the join model must be
@@ -1389,12 +1180,12 @@ module ActiveRecord
1389
1180
  # <tt>has_many :comments, -> { where published: true }, dependent: :destroy</tt> and <tt>destroy</tt> is
1390
1181
  # called on a post, only published comments are destroyed. This means that any unpublished comments in the
1391
1182
  # database would still contain a foreign key pointing to the now deleted post.
1392
- # [:counter_cache]
1183
+ # [+:counter_cache+]
1393
1184
  # This option can be used to configure a custom named <tt>:counter_cache.</tt> You only need this option,
1394
1185
  # when you customized the name of your <tt>:counter_cache</tt> on the #belongs_to association.
1395
- # [:as]
1186
+ # [+:as+]
1396
1187
  # Specifies a polymorphic interface (See #belongs_to).
1397
- # [:through]
1188
+ # [+:through+]
1398
1189
  # Specifies an association through which to perform the query. This can be any other type
1399
1190
  # of association, including other <tt>:through</tt> associations. Options for <tt>:class_name</tt>,
1400
1191
  # <tt>:primary_key</tt> and <tt>:foreign_key</tt> are ignored, as the association uses the
@@ -1408,20 +1199,28 @@ module ActiveRecord
1408
1199
  # If you are going to modify the association (rather than just read from it), then it is
1409
1200
  # a good idea to set the <tt>:inverse_of</tt> option on the source association on the
1410
1201
  # join model. This allows associated records to be built which will automatically create
1411
- # the appropriate join model records when they are saved. (See the 'Association Join Models'
1412
- # section above.)
1413
- # [:source]
1202
+ # the appropriate join model records when they are saved. See
1203
+ # {Association Join Models}[rdoc-ref:Associations::ClassMethods@Association+Join+Models]
1204
+ # and {Setting Inverses}[rdoc-ref:Associations::ClassMethods@Setting+Inverses] for
1205
+ # more detail.
1206
+ #
1207
+ # [+:disable_joins+]
1208
+ # Specifies whether joins should be skipped for an association. If set to true, two or more queries
1209
+ # will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory
1210
+ # due to database limitations. This option is only applicable on <tt>has_many :through</tt> associations as
1211
+ # +has_many+ alone do not perform a join.
1212
+ # [+:source+]
1414
1213
  # Specifies the source association name used by #has_many <tt>:through</tt> queries.
1415
1214
  # Only use it if the name cannot be inferred from the association.
1416
1215
  # <tt>has_many :subscribers, through: :subscriptions</tt> will look for either <tt>:subscribers</tt> or
1417
1216
  # <tt>:subscriber</tt> on Subscription, unless a <tt>:source</tt> is given.
1418
- # [:source_type]
1217
+ # [+:source_type+]
1419
1218
  # Specifies type of the source association used by #has_many <tt>:through</tt> queries where the source
1420
1219
  # association is a polymorphic #belongs_to.
1421
- # [:validate]
1220
+ # [+:validate+]
1422
1221
  # When set to +true+, validates new objects added to association when saving the parent object. +true+ by default.
1423
1222
  # If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
1424
- # [:autosave]
1223
+ # [+:autosave+]
1425
1224
  # If true, always save the associated objects or destroy them if marked for destruction,
1426
1225
  # when saving the parent object. If false, never save or destroy the associated objects.
1427
1226
  # By default, only save associated objects that are new records. This option is implemented as a
@@ -1430,19 +1229,32 @@ module ActiveRecord
1430
1229
  #
1431
1230
  # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
1432
1231
  # <tt>:autosave</tt> to <tt>true</tt>.
1433
- # [:inverse_of]
1232
+ # [+:inverse_of+]
1434
1233
  # Specifies the name of the #belongs_to association on the associated object
1435
1234
  # that is the inverse of this #has_many association.
1436
- # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1437
- # [:extend]
1235
+ # See {Bi-directional associations}[rdoc-ref:Associations::ClassMethods@Bi-directional+associations]
1236
+ # for more detail.
1237
+ # [+:extend+]
1438
1238
  # Specifies a module or array of modules that will be extended into the association object returned.
1439
1239
  # Useful for defining methods on associations, especially when they should be shared between multiple
1440
1240
  # association objects.
1441
- # [:strict_loading]
1442
- # Enforces strict loading every time the associated record is loaded through this association.
1443
- # [:ensuring_owner_was]
1241
+ # [+:strict_loading+]
1242
+ # When set to +true+, enforces strict loading every time the associated record is loaded through this
1243
+ # association.
1244
+ # [+:ensuring_owner_was+]
1444
1245
  # Specifies an instance method to be called on the owner. The method must return true in order for the
1445
1246
  # associated records to be deleted in a background job.
1247
+ # [+:query_constraints+]
1248
+ # Serves as a composite foreign key. Defines the list of columns to be used to query the associated object.
1249
+ # This is an optional option. By default Rails will attempt to derive the value automatically.
1250
+ # When the value is set the Array size must match associated model's primary key or +query_constraints+ size.
1251
+ # [+:index_errors+]
1252
+ # Allows differentiation of multiple validation errors from the association records, by including
1253
+ # an index in the error attribute name, e.g. +roles[2].level+.
1254
+ # When set to +true+, the index is based on association order, i.e. database order, with yet to be
1255
+ # persisted new records placed at the end.
1256
+ # When set to +:nested_attributes_order+, the index is based on the record order received by
1257
+ # nested attributes setter, when accepts_nested_attributes_for is used.
1446
1258
  #
1447
1259
  # Option examples:
1448
1260
  # has_many :comments, -> { order("posted_on") }
@@ -1453,53 +1265,69 @@ module ActiveRecord
1453
1265
  # has_many :tags, as: :taggable
1454
1266
  # has_many :reports, -> { readonly }
1455
1267
  # has_many :subscribers, through: :subscriptions, source: :user
1268
+ # has_many :subscribers, through: :subscriptions, disable_joins: true
1456
1269
  # has_many :comments, strict_loading: true
1270
+ # has_many :comments, query_constraints: [:blog_id, :post_id]
1271
+ # has_many :comments, index_errors: :nested_attributes_order
1457
1272
  def has_many(name, scope = nil, **options, &extension)
1458
1273
  reflection = Builder::HasMany.build(self, name, scope, options, &extension)
1459
1274
  Reflection.add_reflection self, name, reflection
1460
1275
  end
1461
1276
 
1462
- # Specifies a one-to-one association with another class. This method should only be used
1463
- # if the other class contains the foreign key. If the current class contains the foreign key,
1464
- # then you should use #belongs_to instead. See also ActiveRecord::Associations::ClassMethods's overview
1465
- # on when to use #has_one and when to use #belongs_to.
1277
+ # Specifies a one-to-one association with another class. This method
1278
+ # should only be used if the other class contains the foreign key. If
1279
+ # the current class contains the foreign key, then you should use
1280
+ # #belongs_to instead. See {Is it a belongs_to or has_one
1281
+ # association?}[rdoc-ref:Associations::ClassMethods@Is+it+a+-23belongs_to+or+-23has_one+association-3F]
1282
+ # for more detail on when to use #has_one and when to use #belongs_to.
1466
1283
  #
1467
1284
  # The following methods for retrieval and query of a single associated object will be added:
1468
1285
  #
1469
1286
  # +association+ is a placeholder for the symbol passed as the +name+ argument, so
1470
1287
  # <tt>has_one :manager</tt> would add among others <tt>manager.nil?</tt>.
1471
1288
  #
1472
- # [association]
1289
+ # [<tt>association</tt>]
1473
1290
  # Returns the associated object. +nil+ is returned if none is found.
1474
- # [association=(associate)]
1291
+ # [<tt>association=(associate)</tt>]
1475
1292
  # Assigns the associate object, extracts the primary key, sets it as the foreign key,
1476
1293
  # and saves the associate object. To avoid database inconsistencies, permanently deletes an existing
1477
1294
  # associated object when assigning a new one, even if the new one isn't saved to database.
1478
- # [build_association(attributes = {})]
1295
+ # [<tt>build_association(attributes = {})</tt>]
1479
1296
  # Returns a new object of the associated type that has been instantiated
1480
1297
  # with +attributes+ and linked to this object through a foreign key, but has not
1481
1298
  # yet been saved.
1482
- # [create_association(attributes = {})]
1299
+ # [<tt>create_association(attributes = {})</tt>]
1483
1300
  # Returns a new object of the associated type that has been instantiated
1484
1301
  # with +attributes+, linked to this object through a foreign key, and that
1485
1302
  # has already been saved (if it passed the validation).
1486
- # [create_association!(attributes = {})]
1303
+ # [<tt>create_association!(attributes = {})</tt>]
1487
1304
  # Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
1488
1305
  # if the record is invalid.
1489
- # [reload_association]
1306
+ # [<tt>reload_association</tt>]
1490
1307
  # Returns the associated object, forcing a database read.
1308
+ # [<tt>reset_association</tt>]
1309
+ # Unloads the associated object. The next access will query it from the database.
1310
+ #
1311
+ # ==== Example
1312
+ #
1313
+ # class Account < ActiveRecord::Base
1314
+ # has_one :beneficiary
1315
+ # end
1316
+ #
1317
+ # Declaring <tt>has_one :beneficiary</tt> adds the following methods (and more):
1491
1318
  #
1492
- # === Example
1319
+ # account = Account.find(5)
1320
+ # beneficiary = Beneficiary.find(8)
1493
1321
  #
1494
- # An Account class declares <tt>has_one :beneficiary</tt>, which will add:
1495
- # * <tt>Account#beneficiary</tt> (similar to <tt>Beneficiary.where(account_id: id).first</tt>)
1496
- # * <tt>Account#beneficiary=(beneficiary)</tt> (similar to <tt>beneficiary.account_id = account.id; beneficiary.save</tt>)
1497
- # * <tt>Account#build_beneficiary</tt> (similar to <tt>Beneficiary.new(account_id: id)</tt>)
1498
- # * <tt>Account#create_beneficiary</tt> (similar to <tt>b = Beneficiary.new(account_id: id); b.save; b</tt>)
1499
- # * <tt>Account#create_beneficiary!</tt> (similar to <tt>b = Beneficiary.new(account_id: id); b.save!; b</tt>)
1500
- # * <tt>Account#reload_beneficiary</tt>
1322
+ # account.beneficiary # similar to Beneficiary.find_by(account_id: 5)
1323
+ # account.beneficiary = beneficiary # similar to beneficiary.update(account_id: 5)
1324
+ # account.build_beneficiary # similar to Beneficiary.new(account_id: 5)
1325
+ # account.create_beneficiary # similar to Beneficiary.create(account_id: 5)
1326
+ # account.create_beneficiary! # similar to Beneficiary.create!(account_id: 5)
1327
+ # account.reload_beneficiary
1328
+ # account.reset_beneficiary
1501
1329
  #
1502
- # === Scopes
1330
+ # ==== Scopes
1503
1331
  #
1504
1332
  # You can pass a second argument +scope+ as a callable (i.e. proc or
1505
1333
  # lambda) to retrieve a specific record or customize the generated query
@@ -1510,16 +1338,16 @@ module ActiveRecord
1510
1338
  # has_one :employer, -> { joins(:company) }
1511
1339
  # has_one :latest_post, ->(blog) { where("created_at > ?", blog.enabled_at) }
1512
1340
  #
1513
- # === Options
1341
+ # ==== Options
1514
1342
  #
1515
1343
  # The declaration can also include an +options+ hash to specialize the behavior of the association.
1516
1344
  #
1517
1345
  # Options are:
1518
- # [:class_name]
1346
+ # [+:class_name+]
1519
1347
  # Specify the class name of the association. Use it only if that name can't be inferred
1520
1348
  # from the association name. So <tt>has_one :manager</tt> will by default be linked to the Manager class, but
1521
1349
  # if the real class name is Person, you'll have to specify it with this option.
1522
- # [:dependent]
1350
+ # [+:dependent+]
1523
1351
  # Controls what happens to the associated object when
1524
1352
  # its owner is destroyed:
1525
1353
  #
@@ -1531,66 +1359,97 @@ module ActiveRecord
1531
1359
  # * <tt>:delete</tt> causes the associated object to be deleted directly from the database (so callbacks will not execute)
1532
1360
  # * <tt>:nullify</tt> causes the foreign key to be set to +NULL+. Polymorphic type column is also nullified
1533
1361
  # on polymorphic associations. Callbacks are not executed.
1534
- # * <tt>:restrict_with_exception</tt> causes an <tt>ActiveRecord::DeleteRestrictionError</tt> exception to be raised if there is an associated record
1362
+ # * <tt>:restrict_with_exception</tt> causes an ActiveRecord::DeleteRestrictionError exception to be raised if there is an associated record
1535
1363
  # * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there is an associated object
1536
1364
  #
1537
1365
  # Note that <tt>:dependent</tt> option is ignored when using <tt>:through</tt> option.
1538
- # [:foreign_key]
1366
+ # [+:foreign_key+]
1539
1367
  # Specify the foreign key used for the association. By default this is guessed to be the name
1540
1368
  # of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_one association
1541
1369
  # will use "person_id" as the default <tt>:foreign_key</tt>.
1542
1370
  #
1543
- # If you are going to modify the association (rather than just read from it), then it is
1544
- # a good idea to set the <tt>:inverse_of</tt> option.
1545
- # [:foreign_type]
1371
+ # Setting the <tt>:foreign_key</tt> option prevents automatic detection of the association's
1372
+ # inverse, so it is generally a good idea to set the <tt>:inverse_of</tt> option as well.
1373
+ # [+:foreign_type+]
1546
1374
  # Specify the column used to store the associated object's type, if this is a polymorphic
1547
1375
  # association. By default this is guessed to be the name of the polymorphic association
1548
1376
  # specified on "as" option with a "_type" suffix. So a class that defines a
1549
1377
  # <tt>has_one :tag, as: :taggable</tt> association will use "taggable_type" as the
1550
1378
  # default <tt>:foreign_type</tt>.
1551
- # [:primary_key]
1379
+ # [+:primary_key+]
1552
1380
  # Specify the method that returns the primary key used for the association. By default this is +id+.
1553
- # [:as]
1381
+ # [+:as+]
1554
1382
  # Specifies a polymorphic interface (See #belongs_to).
1555
- # [:through]
1383
+ # [+:through+]
1556
1384
  # Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt>,
1557
1385
  # <tt>:primary_key</tt>, and <tt>:foreign_key</tt> are ignored, as the association uses the
1558
1386
  # source reflection. You can only use a <tt>:through</tt> query through a #has_one
1559
1387
  # or #belongs_to association on the join model.
1560
1388
  #
1389
+ # If the association on the join model is a #belongs_to, the collection can be modified
1390
+ # and the records on the <tt>:through</tt> model will be automatically created and removed
1391
+ # as appropriate. Otherwise, the collection is read-only, so you should manipulate the
1392
+ # <tt>:through</tt> association directly.
1393
+ #
1561
1394
  # If you are going to modify the association (rather than just read from it), then it is
1562
- # a good idea to set the <tt>:inverse_of</tt> option.
1563
- # [:source]
1395
+ # a good idea to set the <tt>:inverse_of</tt> option on the source association on the
1396
+ # join model. This allows associated records to be built which will automatically create
1397
+ # the appropriate join model records when they are saved. See
1398
+ # {Association Join Models}[rdoc-ref:Associations::ClassMethods@Association+Join+Models]
1399
+ # and {Setting Inverses}[rdoc-ref:Associations::ClassMethods@Setting+Inverses] for
1400
+ # more detail.
1401
+ # [+:disable_joins+]
1402
+ # Specifies whether joins should be skipped for an association. If set to true, two or more queries
1403
+ # will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory
1404
+ # due to database limitations. This option is only applicable on <tt>has_one :through</tt> associations as
1405
+ # +has_one+ alone does not perform a join.
1406
+ # [+:source+]
1564
1407
  # Specifies the source association name used by #has_one <tt>:through</tt> queries.
1565
1408
  # Only use it if the name cannot be inferred from the association.
1566
1409
  # <tt>has_one :favorite, through: :favorites</tt> will look for a
1567
1410
  # <tt>:favorite</tt> on Favorite, unless a <tt>:source</tt> is given.
1568
- # [:source_type]
1411
+ # [+:source_type+]
1569
1412
  # Specifies type of the source association used by #has_one <tt>:through</tt> queries where the source
1570
1413
  # association is a polymorphic #belongs_to.
1571
- # [:validate]
1414
+ # [+:validate+]
1572
1415
  # When set to +true+, validates new objects added to association when saving the parent object. +false+ by default.
1573
1416
  # If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
1574
- # [:autosave]
1575
- # If true, always save the associated object or destroy it if marked for destruction,
1576
- # when saving the parent object. If false, never save or destroy the associated object.
1577
- # By default, only save the associated object if it's a new record.
1417
+ # [+:autosave+]
1418
+ # If +true+, always saves the associated object or destroys it if marked for destruction,
1419
+ # when saving the parent object.
1420
+ # If +false+, never save or destroy the associated object.
1421
+ #
1422
+ # By default, only saves the associated object if it's a new record. Setting this option
1423
+ # to +true+ also enables validations on the associated object unless explicitly disabled
1424
+ # with <tt>validate: false</tt>. This is because saving an object with invalid associated
1425
+ # objects would fail, so any associated objects will go through validation checks.
1578
1426
  #
1579
1427
  # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
1580
1428
  # <tt>:autosave</tt> to <tt>true</tt>.
1581
- # [:inverse_of]
1429
+ # [+:touch+]
1430
+ # If true, the associated object will be touched (the +updated_at+ / +updated_on+ attributes set to current time)
1431
+ # when this record is either saved or destroyed. If you specify a symbol, that attribute
1432
+ # will be updated with the current time in addition to the +updated_at+ / +updated_on+ attribute.
1433
+ # Please note that no validation will be performed when touching, and only the +after_touch+,
1434
+ # +after_commit+, and +after_rollback+ callbacks will be executed.
1435
+ # [+:inverse_of+]
1582
1436
  # Specifies the name of the #belongs_to association on the associated object
1583
1437
  # that is the inverse of this #has_one association.
1584
- # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1585
- # [:required]
1438
+ # See {Bi-directional associations}[rdoc-ref:Associations::ClassMethods@Bi-directional+associations]
1439
+ # for more detail.
1440
+ # [+:required+]
1586
1441
  # When set to +true+, the association will also have its presence validated.
1587
1442
  # This will validate the association itself, not the id. You can use
1588
1443
  # +:inverse_of+ to avoid an extra query during validation.
1589
- # [:strict_loading]
1444
+ # [+:strict_loading+]
1590
1445
  # Enforces strict loading every time the associated record is loaded through this association.
1591
- # [:ensuring_owner_was]
1446
+ # [+:ensuring_owner_was+]
1592
1447
  # Specifies an instance method to be called on the owner. The method must return true in order for the
1593
1448
  # associated records to be deleted in a background job.
1449
+ # [+:query_constraints+]
1450
+ # Serves as a composite foreign key. Defines the list of columns to be used to query the associated object.
1451
+ # This is an optional option. By default Rails will attempt to derive the value automatically.
1452
+ # When the value is set the Array size must match associated model's primary key or +query_constraints+ size.
1594
1453
  #
1595
1454
  # Option examples:
1596
1455
  # has_one :credit_card, dependent: :destroy # destroys the associated credit card
@@ -1601,18 +1460,22 @@ module ActiveRecord
1601
1460
  # has_one :attachment, as: :attachable
1602
1461
  # has_one :boss, -> { readonly }
1603
1462
  # has_one :club, through: :membership
1463
+ # has_one :club, through: :membership, disable_joins: true
1604
1464
  # has_one :primary_address, -> { where(primary: true) }, through: :addressables, source: :addressable
1605
1465
  # has_one :credit_card, required: true
1606
1466
  # has_one :credit_card, strict_loading: true
1467
+ # has_one :employment_record_book, query_constraints: [:organization_id, :employee_id]
1607
1468
  def has_one(name, scope = nil, **options)
1608
1469
  reflection = Builder::HasOne.build(self, name, scope, options)
1609
1470
  Reflection.add_reflection self, name, reflection
1610
1471
  end
1611
1472
 
1612
- # Specifies a one-to-one association with another class. This method should only be used
1613
- # if this class contains the foreign key. If the other class contains the foreign key,
1614
- # then you should use #has_one instead. See also ActiveRecord::Associations::ClassMethods's overview
1615
- # on when to use #has_one and when to use #belongs_to.
1473
+ # Specifies a one-to-one association with another class. This method
1474
+ # should only be used if this class contains the foreign key. If the
1475
+ # other class contains the foreign key, then you should use #has_one
1476
+ # instead. See {Is it a belongs_to or has_one
1477
+ # association?}[rdoc-ref:Associations::ClassMethods@Is+it+a+-23belongs_to+or+-23has_one+association-3F]
1478
+ # for more detail on when to use #has_one and when to use #belongs_to.
1616
1479
  #
1617
1480
  # Methods will be added for retrieval and query for a single associated object, for which
1618
1481
  # this object holds an id:
@@ -1620,36 +1483,52 @@ module ActiveRecord
1620
1483
  # +association+ is a placeholder for the symbol passed as the +name+ argument, so
1621
1484
  # <tt>belongs_to :author</tt> would add among others <tt>author.nil?</tt>.
1622
1485
  #
1623
- # [association]
1486
+ # [<tt>association</tt>]
1624
1487
  # Returns the associated object. +nil+ is returned if none is found.
1625
- # [association=(associate)]
1488
+ # [<tt>association=(associate)</tt>]
1626
1489
  # Assigns the associate object, extracts the primary key, and sets it as the foreign key.
1627
1490
  # No modification or deletion of existing records takes place.
1628
- # [build_association(attributes = {})]
1491
+ # [<tt>build_association(attributes = {})</tt>]
1629
1492
  # Returns a new object of the associated type that has been instantiated
1630
1493
  # with +attributes+ and linked to this object through a foreign key, but has not yet been saved.
1631
- # [create_association(attributes = {})]
1494
+ # [<tt>create_association(attributes = {})</tt>]
1632
1495
  # Returns a new object of the associated type that has been instantiated
1633
1496
  # with +attributes+, linked to this object through a foreign key, and that
1634
1497
  # has already been saved (if it passed the validation).
1635
- # [create_association!(attributes = {})]
1498
+ # [<tt>create_association!(attributes = {})</tt>]
1636
1499
  # Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
1637
1500
  # if the record is invalid.
1638
- # [reload_association]
1501
+ # [<tt>reload_association</tt>]
1639
1502
  # Returns the associated object, forcing a database read.
1503
+ # [<tt>reset_association</tt>]
1504
+ # Unloads the associated object. The next access will query it from the database.
1505
+ # [<tt>association_changed?</tt>]
1506
+ # Returns true if a new associate object has been assigned and the next save will update the foreign key.
1507
+ # [<tt>association_previously_changed?</tt>]
1508
+ # Returns true if the previous save updated the association to reference a new associate object.
1640
1509
  #
1641
- # === Example
1510
+ # ==== Example
1642
1511
  #
1643
- # A Post class declares <tt>belongs_to :author</tt>, which will add:
1644
- # * <tt>Post#author</tt> (similar to <tt>Author.find(author_id)</tt>)
1645
- # * <tt>Post#author=(author)</tt> (similar to <tt>post.author_id = author.id</tt>)
1646
- # * <tt>Post#build_author</tt> (similar to <tt>post.author = Author.new</tt>)
1647
- # * <tt>Post#create_author</tt> (similar to <tt>post.author = Author.new; post.author.save; post.author</tt>)
1648
- # * <tt>Post#create_author!</tt> (similar to <tt>post.author = Author.new; post.author.save!; post.author</tt>)
1649
- # * <tt>Post#reload_author</tt>
1650
- # The declaration can also include an +options+ hash to specialize the behavior of the association.
1512
+ # class Post < ActiveRecord::Base
1513
+ # belongs_to :author
1514
+ # end
1515
+ #
1516
+ # Declaring <tt>belongs_to :author</tt> adds the following methods (and more):
1651
1517
  #
1652
- # === Scopes
1518
+ # post = Post.find(7)
1519
+ # author = Author.find(19)
1520
+ #
1521
+ # post.author # similar to Author.find(post.author_id)
1522
+ # post.author = author # similar to post.author_id = author.id
1523
+ # post.build_author # similar to post.author = Author.new
1524
+ # post.create_author # similar to post.author = Author.new; post.author.save; post.author
1525
+ # post.create_author! # similar to post.author = Author.new; post.author.save!; post.author
1526
+ # post.reload_author
1527
+ # post.reset_author
1528
+ # post.author_changed?
1529
+ # post.author_previously_changed?
1530
+ #
1531
+ # ==== Scopes
1653
1532
  #
1654
1533
  # You can pass a second argument +scope+ as a callable (i.e. proc or
1655
1534
  # lambda) to retrieve a specific record or customize the generated query
@@ -1660,56 +1539,68 @@ module ActiveRecord
1660
1539
  # belongs_to :user, -> { joins(:friends) }
1661
1540
  # belongs_to :level, ->(game) { where("game_level > ?", game.current_level) }
1662
1541
  #
1663
- # === Options
1542
+ # ==== Options
1664
1543
  #
1665
- # [:class_name]
1544
+ # The declaration can also include an +options+ hash to specialize the behavior of the association.
1545
+ #
1546
+ # [+:class_name+]
1666
1547
  # Specify the class name of the association. Use it only if that name can't be inferred
1667
1548
  # from the association name. So <tt>belongs_to :author</tt> will by default be linked to the Author class, but
1668
1549
  # if the real class name is Person, you'll have to specify it with this option.
1669
- # [:foreign_key]
1550
+ # [+:foreign_key+]
1670
1551
  # Specify the foreign key used for the association. By default this is guessed to be the name
1671
1552
  # of the association with an "_id" suffix. So a class that defines a <tt>belongs_to :person</tt>
1672
1553
  # association will use "person_id" as the default <tt>:foreign_key</tt>. Similarly,
1673
1554
  # <tt>belongs_to :favorite_person, class_name: "Person"</tt> will use a foreign key
1674
1555
  # of "favorite_person_id".
1675
1556
  #
1676
- # If you are going to modify the association (rather than just read from it), then it is
1677
- # a good idea to set the <tt>:inverse_of</tt> option.
1678
- # [:foreign_type]
1557
+ # Setting the <tt>:foreign_key</tt> option prevents automatic detection of the association's
1558
+ # inverse, so it is generally a good idea to set the <tt>:inverse_of</tt> option as well.
1559
+ # [+:foreign_type+]
1679
1560
  # Specify the column used to store the associated object's type, if this is a polymorphic
1680
1561
  # association. By default this is guessed to be the name of the association with a "_type"
1681
1562
  # suffix. So a class that defines a <tt>belongs_to :taggable, polymorphic: true</tt>
1682
1563
  # association will use "taggable_type" as the default <tt>:foreign_type</tt>.
1683
- # [:primary_key]
1564
+ # [+:primary_key+]
1684
1565
  # Specify the method that returns the primary key of associated object used for the association.
1685
1566
  # By default this is +id+.
1686
- # [:dependent]
1567
+ # [+:dependent+]
1687
1568
  # If set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to
1688
1569
  # <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method. If set to
1689
1570
  # <tt>:destroy_async</tt>, the associated object is scheduled to be destroyed in a background job.
1690
1571
  # This option should not be specified when #belongs_to is used in conjunction with
1691
1572
  # a #has_many relationship on another class because of the potential to leave
1692
1573
  # orphaned records behind.
1693
- # [:counter_cache]
1574
+ # [+:counter_cache+]
1694
1575
  # Caches the number of belonging objects on the associate class through the use of CounterCache::ClassMethods#increment_counter
1695
1576
  # and CounterCache::ClassMethods#decrement_counter. The counter cache is incremented when an object of this
1696
1577
  # class is created and decremented when it's destroyed. This requires that a column
1697
1578
  # named <tt>#{table_name}_count</tt> (such as +comments_count+ for a belonging Comment class)
1698
1579
  # is used on the associate class (such as a Post class) - that is the migration for
1699
1580
  # <tt>#{table_name}_count</tt> is created on the associate class (such that <tt>Post.comments_count</tt> will
1700
- # return the count cached, see note below). You can also specify a custom counter
1581
+ # return the count cached). You can also specify a custom counter
1701
1582
  # cache column by providing a column name instead of a +true+/+false+ value to this
1702
1583
  # option (e.g., <tt>counter_cache: :my_custom_counter</tt>.)
1703
- # Note: Specifying a counter cache will add it to that model's list of readonly attributes
1704
- # using +attr_readonly+.
1705
- # [:polymorphic]
1706
- # Specify this association is a polymorphic association by passing +true+.
1584
+ #
1585
+ # Starting to use counter caches on existing large tables can be troublesome, because the column
1586
+ # values must be backfilled separately of the column addition (to not lock the table for too long)
1587
+ # and before the use of +:counter_cache+ (otherwise methods like +size+/+any?+/etc, which use
1588
+ # counter caches internally, can produce incorrect results). To safely backfill the values while keeping
1589
+ # counter cache columns updated with the child records creation/removal and to avoid the mentioned methods
1590
+ # use the possibly incorrect counter cache column values and always get the results from the database,
1591
+ # use <tt>counter_cache: { active: false }</tt>.
1592
+ # If you also need to specify a custom column name, use <tt>counter_cache: { active: false, column: :my_custom_counter }</tt>.
1593
+ #
1707
1594
  # Note: If you've enabled the counter cache, then you may want to add the counter cache attribute
1708
1595
  # to the +attr_readonly+ list in the associated classes (e.g. <tt>class Post; attr_readonly :comments_count; end</tt>).
1709
- # [:validate]
1596
+ # [+:polymorphic+]
1597
+ # Specify this association is a polymorphic association by passing +true+.
1598
+ # Note: Since polymorphic associations rely on storing class names in the database, make sure to update the class names in the
1599
+ # <tt>*_type</tt> polymorphic type column of the corresponding rows.
1600
+ # [+:validate+]
1710
1601
  # When set to +true+, validates new objects added to association when saving the parent object. +false+ by default.
1711
1602
  # If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
1712
- # [:autosave]
1603
+ # [+:autosave+]
1713
1604
  # If true, always save the associated object or destroy it if marked for destruction, when
1714
1605
  # saving the parent object.
1715
1606
  # If false, never save or destroy the associated object.
@@ -1717,32 +1608,38 @@ module ActiveRecord
1717
1608
  #
1718
1609
  # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for
1719
1610
  # sets <tt>:autosave</tt> to <tt>true</tt>.
1720
- # [:touch]
1721
- # If true, the associated object will be touched (the updated_at/on attributes set to current time)
1611
+ # [+:touch+]
1612
+ # If true, the associated object will be touched (the +updated_at+ / +updated_on+ attributes set to current time)
1722
1613
  # when this record is either saved or destroyed. If you specify a symbol, that attribute
1723
- # will be updated with the current time in addition to the updated_at/on attribute.
1724
- # Please note that with touching no validation is performed and only the +after_touch+,
1725
- # +after_commit+ and +after_rollback+ callbacks are executed.
1726
- # [:inverse_of]
1614
+ # will be updated with the current time in addition to the +updated_at+ / +updated_on+ attribute.
1615
+ # Please note that no validation will be performed when touching, and only the +after_touch+,
1616
+ # +after_commit+, and +after_rollback+ callbacks will be executed.
1617
+ # [+:inverse_of+]
1727
1618
  # Specifies the name of the #has_one or #has_many association on the associated
1728
1619
  # object that is the inverse of this #belongs_to association.
1729
- # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1730
- # [:optional]
1620
+ # See {Bi-directional associations}[rdoc-ref:Associations::ClassMethods@Bi-directional+associations]
1621
+ # for more detail.
1622
+ # [+:optional+]
1731
1623
  # When set to +true+, the association will not have its presence validated.
1732
- # [:required]
1624
+ # [+:required+]
1733
1625
  # When set to +true+, the association will also have its presence validated.
1734
1626
  # This will validate the association itself, not the id. You can use
1735
1627
  # +:inverse_of+ to avoid an extra query during validation.
1736
1628
  # NOTE: <tt>required</tt> is set to <tt>true</tt> by default and is deprecated. If
1737
1629
  # you don't want to have association presence validated, use <tt>optional: true</tt>.
1738
- # [:default]
1630
+ # [+:default+]
1739
1631
  # Provide a callable (i.e. proc or lambda) to specify that the association should
1740
1632
  # be initialized with a particular record before validation.
1741
- # [:strict_loading]
1633
+ # Please note that callable won't be executed if the record exists.
1634
+ # [+:strict_loading+]
1742
1635
  # Enforces strict loading every time the associated record is loaded through this association.
1743
- # [:ensuring_owner_was]
1636
+ # [+:ensuring_owner_was+]
1744
1637
  # Specifies an instance method to be called on the owner. The method must return true in order for the
1745
1638
  # associated records to be deleted in a background job.
1639
+ # [+:query_constraints+]
1640
+ # Serves as a composite foreign key. Defines the list of columns to be used to query the associated object.
1641
+ # This is an optional option. By default Rails will attempt to derive the value automatically.
1642
+ # When the value is set the Array size must match associated model's primary key or +query_constraints+ size.
1746
1643
  #
1747
1644
  # Option examples:
1748
1645
  # belongs_to :firm, foreign_key: "client_of"
@@ -1758,6 +1655,7 @@ module ActiveRecord
1758
1655
  # belongs_to :user, optional: true
1759
1656
  # belongs_to :account, default: -> { company.account }
1760
1657
  # belongs_to :account, strict_loading: true
1658
+ # belongs_to :note, query_constraints: [:organization_id, :note_id]
1761
1659
  def belongs_to(name, scope = nil, **options)
1762
1660
  reflection = Builder::BelongsTo.build(self, name, scope, options)
1763
1661
  Reflection.add_reflection self, name, reflection
@@ -1780,7 +1678,7 @@ module ActiveRecord
1780
1678
  # The join table should not have a primary key or a model associated with it. You must manually generate the
1781
1679
  # join table with a migration such as this:
1782
1680
  #
1783
- # class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration[6.0]
1681
+ # class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration[7.2]
1784
1682
  # def change
1785
1683
  # create_join_table :developers, :projects
1786
1684
  # end
@@ -1795,71 +1693,80 @@ module ActiveRecord
1795
1693
  # +collection+ is a placeholder for the symbol passed as the +name+ argument, so
1796
1694
  # <tt>has_and_belongs_to_many :categories</tt> would add among others <tt>categories.empty?</tt>.
1797
1695
  #
1798
- # [collection]
1696
+ # [<tt>collection</tt>]
1799
1697
  # Returns a Relation of all the associated objects.
1800
1698
  # An empty Relation is returned if none are found.
1801
- # [collection<<(object, ...)]
1699
+ # [<tt>collection<<(object, ...)</tt>]
1802
1700
  # Adds one or more objects to the collection by creating associations in the join table
1803
1701
  # (<tt>collection.push</tt> and <tt>collection.concat</tt> are aliases to this method).
1804
1702
  # Note that this operation instantly fires update SQL without waiting for the save or update call on the
1805
1703
  # parent object, unless the parent object is a new record.
1806
- # [collection.delete(object, ...)]
1704
+ # [<tt>collection.delete(object, ...)</tt>]
1807
1705
  # Removes one or more objects from the collection by removing their associations from the join table.
1808
1706
  # This does not destroy the objects.
1809
- # [collection.destroy(object, ...)]
1707
+ # [<tt>collection.destroy(object, ...)</tt>]
1810
1708
  # Removes one or more objects from the collection by running destroy on each association in the join table, overriding any dependent option.
1811
1709
  # This does not destroy the objects.
1812
- # [collection=objects]
1710
+ # [<tt>collection=objects</tt>]
1813
1711
  # Replaces the collection's content by deleting and adding objects as appropriate.
1814
- # [collection_singular_ids]
1712
+ # [<tt>collection_singular_ids</tt>]
1815
1713
  # Returns an array of the associated objects' ids.
1816
- # [collection_singular_ids=ids]
1714
+ # [<tt>collection_singular_ids=ids</tt>]
1817
1715
  # Replace the collection by the objects identified by the primary keys in +ids+.
1818
- # [collection.clear]
1716
+ # [<tt>collection.clear</tt>]
1819
1717
  # Removes every object from the collection. This does not destroy the objects.
1820
- # [collection.empty?]
1718
+ # [<tt>collection.empty?</tt>]
1821
1719
  # Returns +true+ if there are no associated objects.
1822
- # [collection.size]
1720
+ # [<tt>collection.size</tt>]
1823
1721
  # Returns the number of associated objects.
1824
- # [collection.find(id)]
1722
+ # [<tt>collection.find(id)</tt>]
1825
1723
  # Finds an associated object responding to the +id+ and that
1826
1724
  # meets the condition that it has to be associated with this object.
1827
1725
  # Uses the same rules as ActiveRecord::FinderMethods#find.
1828
- # [collection.exists?(...)]
1726
+ # [<tt>collection.exists?(...)</tt>]
1829
1727
  # Checks whether an associated object with the given conditions exists.
1830
1728
  # Uses the same rules as ActiveRecord::FinderMethods#exists?.
1831
- # [collection.build(attributes = {})]
1729
+ # [<tt>collection.build(attributes = {})</tt>]
1832
1730
  # Returns a new object of the collection type that has been instantiated
1833
1731
  # with +attributes+ and linked to this object through the join table, but has not yet been saved.
1834
- # [collection.create(attributes = {})]
1732
+ # [<tt>collection.create(attributes = {})</tt>]
1835
1733
  # Returns a new object of the collection type that has been instantiated
1836
1734
  # with +attributes+, linked to this object through the join table, and that has already been
1837
1735
  # saved (if it passed the validation).
1838
- # [collection.reload]
1736
+ # [<tt>collection.reload</tt>]
1839
1737
  # Returns a Relation of all of the associated objects, forcing a database read.
1840
1738
  # An empty Relation is returned if none are found.
1841
1739
  #
1842
- # === Example
1843
- #
1844
- # A Developer class declares <tt>has_and_belongs_to_many :projects</tt>, which will add:
1845
- # * <tt>Developer#projects</tt>
1846
- # * <tt>Developer#projects<<</tt>
1847
- # * <tt>Developer#projects.delete</tt>
1848
- # * <tt>Developer#projects.destroy</tt>
1849
- # * <tt>Developer#projects=</tt>
1850
- # * <tt>Developer#project_ids</tt>
1851
- # * <tt>Developer#project_ids=</tt>
1852
- # * <tt>Developer#projects.clear</tt>
1853
- # * <tt>Developer#projects.empty?</tt>
1854
- # * <tt>Developer#projects.size</tt>
1855
- # * <tt>Developer#projects.find(id)</tt>
1856
- # * <tt>Developer#projects.exists?(...)</tt>
1857
- # * <tt>Developer#projects.build</tt> (similar to <tt>Project.new(developer_id: id)</tt>)
1858
- # * <tt>Developer#projects.create</tt> (similar to <tt>c = Project.new(developer_id: id); c.save; c</tt>)
1859
- # * <tt>Developer#projects.reload</tt>
1740
+ # ==== Example
1741
+ #
1742
+ # class Developer < ActiveRecord::Base
1743
+ # has_and_belongs_to_many :projects
1744
+ # end
1745
+ #
1746
+ # Declaring <tt>has_and_belongs_to_many :projects</tt> adds the following methods (and more):
1747
+ #
1748
+ # developer = Developer.find(11)
1749
+ # project = Project.find(9)
1750
+ #
1751
+ # developer.projects
1752
+ # developer.projects << project
1753
+ # developer.projects.delete(project)
1754
+ # developer.projects.destroy(project)
1755
+ # developer.projects = [project]
1756
+ # developer.project_ids
1757
+ # developer.project_ids = [9]
1758
+ # developer.projects.clear
1759
+ # developer.projects.empty?
1760
+ # developer.projects.size
1761
+ # developer.projects.find(9)
1762
+ # developer.projects.exists?(9)
1763
+ # developer.projects.build # similar to Project.new(developer_id: 11)
1764
+ # developer.projects.create # similar to Project.create(developer_id: 11)
1765
+ # developer.projects.reload
1766
+ #
1860
1767
  # The declaration may include an +options+ hash to specialize the behavior of the association.
1861
1768
  #
1862
- # === Scopes
1769
+ # ==== Scopes
1863
1770
  #
1864
1771
  # You can pass a second argument +scope+ as a callable (i.e. proc or
1865
1772
  # lambda) to retrieve a specific set of records or customize the generated
@@ -1871,11 +1778,11 @@ module ActiveRecord
1871
1778
  # where("default_category = ?", post.default_category)
1872
1779
  # }
1873
1780
  #
1874
- # === Extensions
1781
+ # ==== Extensions
1875
1782
  #
1876
1783
  # The +extension+ argument allows you to pass a block into a
1877
1784
  # has_and_belongs_to_many association. This is useful for adding new
1878
- # finders, creators and other factory-type methods to be used as part of
1785
+ # finders, creators, and other factory-type methods to be used as part of
1879
1786
  # the association.
1880
1787
  #
1881
1788
  # Extension examples:
@@ -1886,33 +1793,33 @@ module ActiveRecord
1886
1793
  # end
1887
1794
  # end
1888
1795
  #
1889
- # === Options
1796
+ # ==== Options
1890
1797
  #
1891
- # [:class_name]
1798
+ # [+:class_name+]
1892
1799
  # Specify the class name of the association. Use it only if that name can't be inferred
1893
1800
  # from the association name. So <tt>has_and_belongs_to_many :projects</tt> will by default be linked to the
1894
1801
  # Project class, but if the real class name is SuperProject, you'll have to specify it with this option.
1895
- # [:join_table]
1802
+ # [+:join_table+]
1896
1803
  # Specify the name of the join table if the default based on lexical order isn't what you want.
1897
1804
  # <b>WARNING:</b> If you're overwriting the table name of either class, the +table_name+ method
1898
1805
  # MUST be declared underneath any #has_and_belongs_to_many declaration in order to work.
1899
- # [:foreign_key]
1806
+ # [+:foreign_key+]
1900
1807
  # Specify the foreign key used for the association. By default this is guessed to be the name
1901
1808
  # of this class in lower-case and "_id" suffixed. So a Person class that makes
1902
1809
  # a #has_and_belongs_to_many association to Project will use "person_id" as the
1903
1810
  # default <tt>:foreign_key</tt>.
1904
1811
  #
1905
- # If you are going to modify the association (rather than just read from it), then it is
1906
- # a good idea to set the <tt>:inverse_of</tt> option.
1907
- # [:association_foreign_key]
1812
+ # Setting the <tt>:foreign_key</tt> option prevents automatic detection of the association's
1813
+ # inverse, so it is generally a good idea to set the <tt>:inverse_of</tt> option as well.
1814
+ # [+:association_foreign_key+]
1908
1815
  # Specify the foreign key used for the association on the receiving side of the association.
1909
1816
  # By default this is guessed to be the name of the associated class in lower-case and "_id" suffixed.
1910
1817
  # So if a Person class makes a #has_and_belongs_to_many association to Project,
1911
1818
  # the association will use "project_id" as the default <tt>:association_foreign_key</tt>.
1912
- # [:validate]
1819
+ # [+:validate+]
1913
1820
  # When set to +true+, validates new objects added to association when saving the parent object. +true+ by default.
1914
1821
  # If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
1915
- # [:autosave]
1822
+ # [+:autosave+]
1916
1823
  # If true, always save the associated objects or destroy them if marked for destruction, when
1917
1824
  # saving the parent object.
1918
1825
  # If false, never save or destroy the associated objects.
@@ -1920,7 +1827,7 @@ module ActiveRecord
1920
1827
  #
1921
1828
  # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
1922
1829
  # <tt>:autosave</tt> to <tt>true</tt>.
1923
- # [:strict_loading]
1830
+ # [+:strict_loading+]
1924
1831
  # Enforces strict loading every time an associated record is loaded through this association.
1925
1832
  #
1926
1833
  # Option examples:
@@ -1965,7 +1872,7 @@ module ActiveRecord
1965
1872
  end
1966
1873
 
1967
1874
  has_many name, scope, **hm_options, &extension
1968
- _reflections[name.to_s].parent_reflection = habtm_reflection
1875
+ _reflections[name].parent_reflection = habtm_reflection
1969
1876
  end
1970
1877
  end
1971
1878
  end