activerecord 6.1.6 → 7.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (309) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1627 -983
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +18 -18
  5. data/lib/active_record/aggregations.rb +17 -14
  6. data/lib/active_record/association_relation.rb +1 -11
  7. data/lib/active_record/associations/association.rb +50 -19
  8. data/lib/active_record/associations/association_scope.rb +17 -12
  9. data/lib/active_record/associations/belongs_to_association.rb +28 -9
  10. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
  11. data/lib/active_record/associations/builder/association.rb +11 -5
  12. data/lib/active_record/associations/builder/belongs_to.rb +40 -14
  13. data/lib/active_record/associations/builder/collection_association.rb +10 -3
  14. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -5
  15. data/lib/active_record/associations/builder/has_many.rb +3 -2
  16. data/lib/active_record/associations/builder/has_one.rb +2 -1
  17. data/lib/active_record/associations/builder/singular_association.rb +6 -2
  18. data/lib/active_record/associations/collection_association.rb +35 -31
  19. data/lib/active_record/associations/collection_proxy.rb +30 -15
  20. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  21. data/lib/active_record/associations/foreign_association.rb +10 -3
  22. data/lib/active_record/associations/has_many_association.rb +28 -18
  23. data/lib/active_record/associations/has_many_through_association.rb +12 -7
  24. data/lib/active_record/associations/has_one_association.rb +20 -10
  25. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  26. data/lib/active_record/associations/join_dependency.rb +26 -16
  27. data/lib/active_record/associations/preloader/association.rb +207 -52
  28. data/lib/active_record/associations/preloader/batch.rb +48 -0
  29. data/lib/active_record/associations/preloader/branch.rb +147 -0
  30. data/lib/active_record/associations/preloader/through_association.rb +50 -14
  31. data/lib/active_record/associations/preloader.rb +50 -121
  32. data/lib/active_record/associations/singular_association.rb +9 -3
  33. data/lib/active_record/associations/through_association.rb +25 -14
  34. data/lib/active_record/associations.rb +439 -305
  35. data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
  36. data/lib/active_record/attribute_assignment.rb +1 -3
  37. data/lib/active_record/attribute_methods/before_type_cast.rb +24 -2
  38. data/lib/active_record/attribute_methods/dirty.rb +73 -22
  39. data/lib/active_record/attribute_methods/primary_key.rb +78 -26
  40. data/lib/active_record/attribute_methods/query.rb +31 -19
  41. data/lib/active_record/attribute_methods/read.rb +25 -10
  42. data/lib/active_record/attribute_methods/serialization.rb +194 -37
  43. data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
  44. data/lib/active_record/attribute_methods/write.rb +10 -13
  45. data/lib/active_record/attribute_methods.rb +121 -40
  46. data/lib/active_record/attributes.rb +27 -38
  47. data/lib/active_record/autosave_association.rb +61 -30
  48. data/lib/active_record/base.rb +25 -2
  49. data/lib/active_record/callbacks.rb +18 -34
  50. data/lib/active_record/coders/column_serializer.rb +61 -0
  51. data/lib/active_record/coders/json.rb +1 -1
  52. data/lib/active_record/coders/yaml_column.rb +70 -34
  53. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +367 -0
  54. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
  55. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +78 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +96 -590
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -17
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +172 -50
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +77 -27
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +87 -73
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +21 -20
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +186 -31
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +360 -138
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +281 -59
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +631 -149
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +285 -156
  69. data/lib/active_record/connection_adapters/column.rb +13 -0
  70. data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
  71. data/lib/active_record/connection_adapters/mysql/database_statements.rb +25 -134
  72. data/lib/active_record/connection_adapters/mysql/quoting.rb +56 -25
  73. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
  74. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
  75. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
  76. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +38 -14
  77. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +151 -0
  78. data/lib/active_record/connection_adapters/mysql2_adapter.rb +104 -53
  79. data/lib/active_record/connection_adapters/pool_config.rb +20 -11
  80. data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +89 -52
  83. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  84. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
  87. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +12 -3
  89. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
  92. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  93. data/lib/active_record/connection_adapters/postgresql/quoting.rb +89 -56
  94. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +28 -0
  95. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +92 -2
  96. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +153 -3
  97. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -0
  98. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +394 -74
  99. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
  100. data/lib/active_record/connection_adapters/postgresql_adapter.rb +509 -247
  101. data/lib/active_record/connection_adapters/schema_cache.rb +319 -90
  102. data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
  103. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +72 -53
  104. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +37 -21
  105. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +7 -0
  106. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -22
  107. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +294 -102
  108. data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
  109. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
  110. data/lib/active_record/connection_adapters/trilogy_adapter.rb +254 -0
  111. data/lib/active_record/connection_adapters.rb +9 -6
  112. data/lib/active_record/connection_handling.rb +107 -136
  113. data/lib/active_record/core.rb +202 -223
  114. data/lib/active_record/counter_cache.rb +46 -25
  115. data/lib/active_record/database_configurations/connection_url_resolver.rb +2 -1
  116. data/lib/active_record/database_configurations/database_config.rb +21 -12
  117. data/lib/active_record/database_configurations/hash_config.rb +84 -16
  118. data/lib/active_record/database_configurations/url_config.rb +18 -12
  119. data/lib/active_record/database_configurations.rb +95 -59
  120. data/lib/active_record/delegated_type.rb +61 -15
  121. data/lib/active_record/deprecator.rb +7 -0
  122. data/lib/active_record/destroy_association_async_job.rb +3 -1
  123. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  124. data/lib/active_record/dynamic_matchers.rb +1 -1
  125. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  126. data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
  127. data/lib/active_record/encryption/cipher.rb +53 -0
  128. data/lib/active_record/encryption/config.rb +68 -0
  129. data/lib/active_record/encryption/configurable.rb +60 -0
  130. data/lib/active_record/encryption/context.rb +42 -0
  131. data/lib/active_record/encryption/contexts.rb +76 -0
  132. data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
  133. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  134. data/lib/active_record/encryption/encryptable_record.rb +224 -0
  135. data/lib/active_record/encryption/encrypted_attribute_type.rb +151 -0
  136. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  137. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  138. data/lib/active_record/encryption/encryptor.rb +155 -0
  139. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  140. data/lib/active_record/encryption/errors.rb +15 -0
  141. data/lib/active_record/encryption/extended_deterministic_queries.rb +157 -0
  142. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  143. data/lib/active_record/encryption/key.rb +28 -0
  144. data/lib/active_record/encryption/key_generator.rb +53 -0
  145. data/lib/active_record/encryption/key_provider.rb +46 -0
  146. data/lib/active_record/encryption/message.rb +33 -0
  147. data/lib/active_record/encryption/message_serializer.rb +92 -0
  148. data/lib/active_record/encryption/null_encryptor.rb +21 -0
  149. data/lib/active_record/encryption/properties.rb +76 -0
  150. data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
  151. data/lib/active_record/encryption/scheme.rb +96 -0
  152. data/lib/active_record/encryption.rb +56 -0
  153. data/lib/active_record/enum.rb +154 -63
  154. data/lib/active_record/errors.rb +171 -15
  155. data/lib/active_record/explain.rb +23 -3
  156. data/lib/active_record/explain_registry.rb +11 -6
  157. data/lib/active_record/explain_subscriber.rb +1 -1
  158. data/lib/active_record/fixture_set/file.rb +15 -1
  159. data/lib/active_record/fixture_set/model_metadata.rb +14 -4
  160. data/lib/active_record/fixture_set/render_context.rb +2 -0
  161. data/lib/active_record/fixture_set/table_row.rb +70 -14
  162. data/lib/active_record/fixture_set/table_rows.rb +4 -4
  163. data/lib/active_record/fixtures.rb +131 -86
  164. data/lib/active_record/future_result.rb +164 -0
  165. data/lib/active_record/gem_version.rb +3 -3
  166. data/lib/active_record/inheritance.rb +81 -29
  167. data/lib/active_record/insert_all.rb +135 -22
  168. data/lib/active_record/integration.rb +11 -10
  169. data/lib/active_record/internal_metadata.rb +119 -33
  170. data/lib/active_record/legacy_yaml_adapter.rb +2 -39
  171. data/lib/active_record/locking/optimistic.rb +36 -21
  172. data/lib/active_record/locking/pessimistic.rb +15 -6
  173. data/lib/active_record/log_subscriber.rb +52 -19
  174. data/lib/active_record/marshalling.rb +56 -0
  175. data/lib/active_record/message_pack.rb +124 -0
  176. data/lib/active_record/middleware/database_selector/resolver.rb +10 -10
  177. data/lib/active_record/middleware/database_selector.rb +23 -13
  178. data/lib/active_record/middleware/shard_selector.rb +62 -0
  179. data/lib/active_record/migration/command_recorder.rb +112 -14
  180. data/lib/active_record/migration/compatibility.rb +221 -48
  181. data/lib/active_record/migration/default_strategy.rb +23 -0
  182. data/lib/active_record/migration/execution_strategy.rb +19 -0
  183. data/lib/active_record/migration/join_table.rb +1 -1
  184. data/lib/active_record/migration/pending_migration_connection.rb +21 -0
  185. data/lib/active_record/migration.rb +358 -171
  186. data/lib/active_record/model_schema.rb +120 -101
  187. data/lib/active_record/nested_attributes.rb +37 -18
  188. data/lib/active_record/no_touching.rb +3 -3
  189. data/lib/active_record/normalization.rb +167 -0
  190. data/lib/active_record/persistence.rb +405 -85
  191. data/lib/active_record/promise.rb +84 -0
  192. data/lib/active_record/query_cache.rb +3 -21
  193. data/lib/active_record/query_logs.rb +174 -0
  194. data/lib/active_record/query_logs_formatter.rb +41 -0
  195. data/lib/active_record/querying.rb +29 -6
  196. data/lib/active_record/railtie.rb +219 -43
  197. data/lib/active_record/railties/controller_runtime.rb +13 -9
  198. data/lib/active_record/railties/databases.rake +188 -252
  199. data/lib/active_record/railties/job_runtime.rb +23 -0
  200. data/lib/active_record/readonly_attributes.rb +41 -3
  201. data/lib/active_record/reflection.rb +241 -80
  202. data/lib/active_record/relation/batches/batch_enumerator.rb +23 -7
  203. data/lib/active_record/relation/batches.rb +192 -63
  204. data/lib/active_record/relation/calculations.rb +219 -90
  205. data/lib/active_record/relation/delegation.rb +27 -13
  206. data/lib/active_record/relation/finder_methods.rb +108 -51
  207. data/lib/active_record/relation/merger.rb +22 -13
  208. data/lib/active_record/relation/predicate_builder/association_query_value.rb +31 -3
  209. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -6
  210. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  211. data/lib/active_record/relation/predicate_builder.rb +27 -20
  212. data/lib/active_record/relation/query_attribute.rb +30 -12
  213. data/lib/active_record/relation/query_methods.rb +654 -127
  214. data/lib/active_record/relation/record_fetch_warning.rb +7 -9
  215. data/lib/active_record/relation/spawn_methods.rb +20 -3
  216. data/lib/active_record/relation/where_clause.rb +10 -19
  217. data/lib/active_record/relation.rb +262 -120
  218. data/lib/active_record/result.rb +37 -11
  219. data/lib/active_record/runtime_registry.rb +18 -13
  220. data/lib/active_record/sanitization.rb +65 -20
  221. data/lib/active_record/schema.rb +36 -22
  222. data/lib/active_record/schema_dumper.rb +73 -24
  223. data/lib/active_record/schema_migration.rb +68 -33
  224. data/lib/active_record/scoping/default.rb +72 -15
  225. data/lib/active_record/scoping/named.rb +5 -13
  226. data/lib/active_record/scoping.rb +65 -34
  227. data/lib/active_record/secure_password.rb +60 -0
  228. data/lib/active_record/secure_token.rb +21 -3
  229. data/lib/active_record/serialization.rb +6 -1
  230. data/lib/active_record/signed_id.rb +10 -8
  231. data/lib/active_record/store.rb +16 -11
  232. data/lib/active_record/suppressor.rb +13 -15
  233. data/lib/active_record/table_metadata.rb +16 -3
  234. data/lib/active_record/tasks/database_tasks.rb +225 -136
  235. data/lib/active_record/tasks/mysql_database_tasks.rb +16 -7
  236. data/lib/active_record/tasks/postgresql_database_tasks.rb +35 -26
  237. data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
  238. data/lib/active_record/test_databases.rb +1 -1
  239. data/lib/active_record/test_fixtures.rb +123 -99
  240. data/lib/active_record/timestamp.rb +29 -18
  241. data/lib/active_record/token_for.rb +113 -0
  242. data/lib/active_record/touch_later.rb +11 -6
  243. data/lib/active_record/transactions.rb +48 -27
  244. data/lib/active_record/translation.rb +3 -3
  245. data/lib/active_record/type/adapter_specific_registry.rb +32 -14
  246. data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
  247. data/lib/active_record/type/internal/timezone.rb +7 -2
  248. data/lib/active_record/type/serialized.rb +9 -5
  249. data/lib/active_record/type/time.rb +4 -0
  250. data/lib/active_record/type/type_map.rb +17 -20
  251. data/lib/active_record/type.rb +1 -2
  252. data/lib/active_record/validations/absence.rb +1 -1
  253. data/lib/active_record/validations/associated.rb +4 -4
  254. data/lib/active_record/validations/numericality.rb +5 -4
  255. data/lib/active_record/validations/presence.rb +5 -28
  256. data/lib/active_record/validations/uniqueness.rb +51 -6
  257. data/lib/active_record/validations.rb +8 -4
  258. data/lib/active_record/version.rb +1 -1
  259. data/lib/active_record.rb +335 -32
  260. data/lib/arel/attributes/attribute.rb +0 -8
  261. data/lib/arel/crud.rb +28 -22
  262. data/lib/arel/delete_manager.rb +18 -4
  263. data/lib/arel/errors.rb +10 -0
  264. data/lib/arel/factory_methods.rb +4 -0
  265. data/lib/arel/filter_predications.rb +9 -0
  266. data/lib/arel/insert_manager.rb +2 -3
  267. data/lib/arel/nodes/and.rb +4 -0
  268. data/lib/arel/nodes/binary.rb +6 -1
  269. data/lib/arel/nodes/bound_sql_literal.rb +61 -0
  270. data/lib/arel/nodes/casted.rb +1 -1
  271. data/lib/arel/nodes/cte.rb +36 -0
  272. data/lib/arel/nodes/delete_statement.rb +12 -13
  273. data/lib/arel/nodes/filter.rb +10 -0
  274. data/lib/arel/nodes/fragments.rb +35 -0
  275. data/lib/arel/nodes/function.rb +1 -0
  276. data/lib/arel/nodes/homogeneous_in.rb +1 -9
  277. data/lib/arel/nodes/insert_statement.rb +2 -2
  278. data/lib/arel/nodes/leading_join.rb +8 -0
  279. data/lib/arel/nodes/node.rb +111 -2
  280. data/lib/arel/nodes/select_core.rb +2 -2
  281. data/lib/arel/nodes/select_statement.rb +2 -2
  282. data/lib/arel/nodes/sql_literal.rb +6 -0
  283. data/lib/arel/nodes/table_alias.rb +4 -0
  284. data/lib/arel/nodes/update_statement.rb +8 -3
  285. data/lib/arel/nodes.rb +5 -0
  286. data/lib/arel/predications.rb +13 -3
  287. data/lib/arel/select_manager.rb +10 -4
  288. data/lib/arel/table.rb +9 -6
  289. data/lib/arel/tree_manager.rb +0 -12
  290. data/lib/arel/update_manager.rb +18 -4
  291. data/lib/arel/visitors/dot.rb +80 -90
  292. data/lib/arel/visitors/mysql.rb +16 -3
  293. data/lib/arel/visitors/postgresql.rb +0 -10
  294. data/lib/arel/visitors/to_sql.rb +139 -19
  295. data/lib/arel/visitors/visitor.rb +2 -2
  296. data/lib/arel.rb +18 -3
  297. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  298. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  299. data/lib/rails/generators/active_record/migration.rb +3 -1
  300. data/lib/rails/generators/active_record/model/USAGE +113 -0
  301. data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
  302. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
  303. data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
  304. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  305. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  306. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  307. metadata +93 -13
  308. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
  309. data/lib/active_record/null_relation.rb +0 -67
@@ -1,11 +1,9 @@
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:
4
+ class AssociationNotFoundError < ConfigurationError # :nodoc:
8
5
  attr_reader :record, :association_name
6
+
9
7
  def initialize(record = nil, association_name = nil)
10
8
  @record = record
11
9
  @association_name = association_name
@@ -16,32 +14,25 @@ module ActiveRecord
16
14
  end
17
15
  end
18
16
 
19
- class Correction
20
- def initialize(error)
21
- @error = error
22
- end
17
+ if defined?(DidYouMean::Correctable) && defined?(DidYouMean::SpellChecker)
18
+ include DidYouMean::Correctable
23
19
 
24
20
  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)
21
+ if record && association_name
22
+ @corrections ||= begin
23
+ maybe_these = record.class.reflections.keys
24
+ DidYouMean::SpellChecker.new(dictionary: maybe_these).correct(association_name)
25
+ end
31
26
  else
32
27
  []
33
28
  end
34
29
  end
35
30
  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
31
  end
42
32
 
43
- class InverseOfAssociationNotFoundError < ActiveRecordError #:nodoc:
33
+ class InverseOfAssociationNotFoundError < ActiveRecordError # :nodoc:
44
34
  attr_reader :reflection, :associated_class
35
+
45
36
  def initialize(reflection = nil, associated_class = nil)
46
37
  if reflection
47
38
  @reflection = reflection
@@ -52,31 +43,35 @@ module ActiveRecord
52
43
  end
53
44
  end
54
45
 
55
- class Correction
56
- def initialize(error)
57
- @error = error
58
- end
46
+ if defined?(DidYouMean::Correctable) && defined?(DidYouMean::SpellChecker)
47
+ include DidYouMean::Correctable
59
48
 
60
49
  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)
50
+ if reflection && associated_class
51
+ @corrections ||= begin
52
+ maybe_these = associated_class.reflections.keys
53
+ DidYouMean::SpellChecker.new(dictionary: maybe_these).correct(reflection.options[:inverse_of].to_s)
54
+ end
67
55
  else
68
56
  []
69
57
  end
70
58
  end
71
59
  end
60
+ end
72
61
 
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)
62
+ class InverseOfAssociationRecursiveError < ActiveRecordError # :nodoc:
63
+ attr_reader :reflection
64
+ def initialize(reflection = nil)
65
+ if reflection
66
+ @reflection = reflection
67
+ super("Inverse association #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{reflection.class_name}) is recursive.")
68
+ else
69
+ super("Inverse association is recursive.")
70
+ end
76
71
  end
77
72
  end
78
73
 
79
- class HasManyThroughAssociationNotFoundError < ActiveRecordError #:nodoc:
74
+ class HasManyThroughAssociationNotFoundError < ActiveRecordError # :nodoc:
80
75
  attr_reader :owner_class, :reflection
81
76
 
82
77
  def initialize(owner_class = nil, reflection = nil)
@@ -89,32 +84,24 @@ module ActiveRecord
89
84
  end
90
85
  end
91
86
 
92
- class Correction
93
- def initialize(error)
94
- @error = error
95
- end
87
+ if defined?(DidYouMean::Correctable) && defined?(DidYouMean::SpellChecker)
88
+ include DidYouMean::Correctable
96
89
 
97
90
  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)
91
+ if owner_class && reflection
92
+ @corrections ||= begin
93
+ maybe_these = owner_class.reflections.keys
94
+ maybe_these -= [reflection.name.to_s] # remove failing reflection
95
+ DidYouMean::SpellChecker.new(dictionary: maybe_these).correct(reflection.options[:through].to_s)
96
+ end
105
97
  else
106
98
  []
107
99
  end
108
100
  end
109
101
  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
102
  end
116
103
 
117
- class HasManyThroughAssociationPolymorphicSourceError < ActiveRecordError #:nodoc:
104
+ class HasManyThroughAssociationPolymorphicSourceError < ActiveRecordError # :nodoc:
118
105
  def initialize(owner_class_name = nil, reflection = nil, source_reflection = nil)
119
106
  if owner_class_name && reflection && source_reflection
120
107
  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.")
@@ -124,7 +111,7 @@ module ActiveRecord
124
111
  end
125
112
  end
126
113
 
127
- class HasManyThroughAssociationPolymorphicThroughError < ActiveRecordError #:nodoc:
114
+ class HasManyThroughAssociationPolymorphicThroughError < ActiveRecordError # :nodoc:
128
115
  def initialize(owner_class_name = nil, reflection = nil)
129
116
  if owner_class_name && reflection
130
117
  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}'.")
@@ -134,7 +121,7 @@ module ActiveRecord
134
121
  end
135
122
  end
136
123
 
137
- class HasManyThroughAssociationPointlessSourceTypeError < ActiveRecordError #:nodoc:
124
+ class HasManyThroughAssociationPointlessSourceTypeError < ActiveRecordError # :nodoc:
138
125
  def initialize(owner_class_name = nil, reflection = nil, source_reflection = nil)
139
126
  if owner_class_name && reflection && source_reflection
140
127
  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.")
@@ -144,7 +131,7 @@ module ActiveRecord
144
131
  end
145
132
  end
146
133
 
147
- class HasOneThroughCantAssociateThroughCollection < ActiveRecordError #:nodoc:
134
+ class HasOneThroughCantAssociateThroughCollection < ActiveRecordError # :nodoc:
148
135
  def initialize(owner_class_name = nil, reflection = nil, through_reflection = nil)
149
136
  if owner_class_name && reflection && through_reflection
150
137
  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.")
@@ -154,7 +141,7 @@ module ActiveRecord
154
141
  end
155
142
  end
156
143
 
157
- class HasOneAssociationPolymorphicThroughError < ActiveRecordError #:nodoc:
144
+ class HasOneAssociationPolymorphicThroughError < ActiveRecordError # :nodoc:
158
145
  def initialize(owner_class_name = nil, reflection = nil)
159
146
  if owner_class_name && reflection
160
147
  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}'.")
@@ -164,7 +151,7 @@ module ActiveRecord
164
151
  end
165
152
  end
166
153
 
167
- class HasManyThroughSourceAssociationNotFoundError < ActiveRecordError #:nodoc:
154
+ class HasManyThroughSourceAssociationNotFoundError < ActiveRecordError # :nodoc:
168
155
  def initialize(reflection = nil)
169
156
  if reflection
170
157
  through_reflection = reflection.through_reflection
@@ -177,7 +164,7 @@ module ActiveRecord
177
164
  end
178
165
  end
179
166
 
180
- class HasManyThroughOrderError < ActiveRecordError #:nodoc:
167
+ class HasManyThroughOrderError < ActiveRecordError # :nodoc:
181
168
  def initialize(owner_class_name = nil, reflection = nil, through_reflection = nil)
182
169
  if owner_class_name && reflection && through_reflection
183
170
  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.")
@@ -187,7 +174,7 @@ module ActiveRecord
187
174
  end
188
175
  end
189
176
 
190
- class ThroughCantAssociateThroughHasOneOrManyReflection < ActiveRecordError #:nodoc:
177
+ class ThroughCantAssociateThroughHasOneOrManyReflection < ActiveRecordError # :nodoc:
191
178
  def initialize(owner = nil, reflection = nil)
192
179
  if owner && reflection
193
180
  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}.")
@@ -197,6 +184,22 @@ module ActiveRecord
197
184
  end
198
185
  end
199
186
 
187
+ class CompositePrimaryKeyMismatchError < ActiveRecordError # :nodoc:
188
+ attr_reader :reflection
189
+
190
+ def initialize(reflection = nil)
191
+ if reflection
192
+ if reflection.has_one? || reflection.collection?
193
+ super("Association #{reflection.active_record}##{reflection.name} primary key #{reflection.active_record_primary_key} doesn't match with foreign key #{reflection.foreign_key}. Please specify query_constraints, or primary_key and foreign_key values.")
194
+ else
195
+ super("Association #{reflection.active_record}##{reflection.name} primary key #{reflection.association_primary_key} doesn't match with foreign key #{reflection.foreign_key}. Please specify query_constraints, or primary_key and foreign_key values.")
196
+ end
197
+ else
198
+ super("Association primary key doesn't match with foreign key.")
199
+ end
200
+ end
201
+ end
202
+
200
203
  class AmbiguousSourceReflectionForThroughAssociation < ActiveRecordError # :nodoc:
201
204
  def initialize(klass, macro, association_name, options, possible_sources)
202
205
  example_options = options.dup
@@ -212,13 +215,13 @@ module ActiveRecord
212
215
  end
213
216
  end
214
217
 
215
- class HasManyThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection #:nodoc:
218
+ class HasManyThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection # :nodoc:
216
219
  end
217
220
 
218
- class HasOneThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection #:nodoc:
221
+ class HasOneThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection # :nodoc:
219
222
  end
220
223
 
221
- class ThroughNestedAssociationsAreReadonly < ActiveRecordError #:nodoc:
224
+ class ThroughNestedAssociationsAreReadonly < ActiveRecordError # :nodoc:
222
225
  def initialize(owner = nil, reflection = nil)
223
226
  if owner && reflection
224
227
  super("Cannot modify association '#{owner.class.name}##{reflection.name}' because it goes through more than one other association.")
@@ -228,10 +231,10 @@ module ActiveRecord
228
231
  end
229
232
  end
230
233
 
231
- class HasManyThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly #:nodoc:
234
+ class HasManyThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly # :nodoc:
232
235
  end
233
236
 
234
- class HasOneThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly #:nodoc:
237
+ class HasOneThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly # :nodoc:
235
238
  end
236
239
 
237
240
  # This error is raised when trying to eager load a polymorphic association using a JOIN.
@@ -250,7 +253,7 @@ module ActiveRecord
250
253
  # This error is raised when trying to destroy a parent instance in N:1 or 1:1 associations
251
254
  # (has_many, has_one) when there is at least 1 child associated instance.
252
255
  # ex: if @project.tasks.size > 0, DeleteRestrictionError will be raised when trying to destroy @project
253
- class DeleteRestrictionError < ActiveRecordError #:nodoc:
256
+ class DeleteRestrictionError < ActiveRecordError # :nodoc:
254
257
  def initialize(name = nil)
255
258
  if name
256
259
  super("Cannot delete record because of dependent #{name}")
@@ -274,7 +277,7 @@ module ActiveRecord
274
277
  autoload :CollectionProxy
275
278
  autoload :ThroughAssociation
276
279
 
277
- module Builder #:nodoc:
280
+ module Builder # :nodoc:
278
281
  autoload :Association, "active_record/associations/builder/association"
279
282
  autoload :SingularAssociation, "active_record/associations/builder/singular_association"
280
283
  autoload :CollectionAssociation, "active_record/associations/builder/collection_association"
@@ -296,16 +299,18 @@ module ActiveRecord
296
299
  autoload :Preloader
297
300
  autoload :JoinDependency
298
301
  autoload :AssociationScope
302
+ autoload :DisableJoinsAssociationScope
299
303
  autoload :AliasTracker
300
304
  end
301
305
 
302
306
  def self.eager_load!
303
307
  super
304
308
  Preloader.eager_load!
309
+ JoinDependency.eager_load!
305
310
  end
306
311
 
307
312
  # Returns the association instance for the given name, instantiating it if it doesn't already exist
308
- def association(name) #:nodoc:
313
+ def association(name) # :nodoc:
309
314
  association = association_instance_get(name)
310
315
 
311
316
  if association.nil?
@@ -328,20 +333,10 @@ module ActiveRecord
328
333
  super
329
334
  end
330
335
 
331
- def reload(*) # :nodoc:
332
- clear_association_cache
333
- super
334
- end
335
-
336
336
  private
337
- # Clears out the association cache.
338
- def clear_association_cache
339
- @association_cache.clear if persisted?
340
- end
341
-
342
337
  def init_internals
343
- @association_cache = {}
344
338
  super
339
+ @association_cache = {}
345
340
  end
346
341
 
347
342
  # Returns the specified association instance if it exists, +nil+ otherwise.
@@ -354,6 +349,8 @@ module ActiveRecord
354
349
  @association_cache[name] = association
355
350
  end
356
351
 
352
+ # = Active Record \Associations
353
+ #
357
354
  # \Associations are a set of macro-like class methods for tying objects together through
358
355
  # foreign keys. They express relationships like "Project has one Project Manager"
359
356
  # or "Project belongs to a Portfolio". Each macro adds a number of methods to the
@@ -370,23 +367,42 @@ module ActiveRecord
370
367
  #
371
368
  # The project class now has the following methods (and more) to ease the traversal and
372
369
  # 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>
370
+ #
371
+ # project = Project.first
372
+ # project.portfolio
373
+ # project.portfolio = Portfolio.first
374
+ # project.reload_portfolio
375
+ #
376
+ # project.project_manager
377
+ # project.project_manager = ProjectManager.first
378
+ # project.reload_project_manager
379
+ #
380
+ # project.milestones.empty?
381
+ # project.milestones.size
382
+ # project.milestones
383
+ # project.milestones << Milestone.first
384
+ # project.milestones.delete(Milestone.first)
385
+ # project.milestones.destroy(Milestone.first)
386
+ # project.milestones.find(Milestone.first.id)
387
+ # project.milestones.build
388
+ # project.milestones.create
389
+ #
390
+ # project.categories.empty?
391
+ # project.categories.size
392
+ # project.categories
393
+ # project.categories << Category.first
394
+ # project.categories.delete(category1)
395
+ # project.categories.destroy(category1)
380
396
  #
381
397
  # === A word of warning
382
398
  #
383
399
  # 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.
400
+ # +ActiveRecord::Base+. Since the association adds a method with that name to
401
+ # 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.
402
+ # 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
403
  #
388
404
  # == Auto-generated methods
389
- # See also Instance Public methods below for more details.
405
+ # See also "Instance Public methods" below ( from #belongs_to ) for more details.
390
406
  #
391
407
  # === Singular associations (one-to-one)
392
408
  # | | belongs_to |
@@ -398,6 +414,8 @@ module ActiveRecord
398
414
  # create_other(attributes={}) | X | | X
399
415
  # create_other!(attributes={}) | X | | X
400
416
  # reload_other | X | X | X
417
+ # other_changed? | X | X |
418
+ # other_previously_changed? | X | X |
401
419
  #
402
420
  # === Collection associations (one-to-many / many-to-many)
403
421
  # | | | has_many
@@ -451,7 +469,7 @@ module ActiveRecord
451
469
  #
452
470
  # == Cardinality and associations
453
471
  #
454
- # Active Record associations can be used to describe one-to-one, one-to-many and many-to-many
472
+ # Active Record associations can be used to describe one-to-one, one-to-many, and many-to-many
455
473
  # relationships between models. Each model uses an association to describe its role in
456
474
  # the relation. The #belongs_to association is always used in the model that has
457
475
  # the foreign key.
@@ -605,8 +623,11 @@ module ActiveRecord
605
623
  # has_many :birthday_events, ->(user) { where(starts_on: user.birthday) }, class_name: 'Event'
606
624
  # end
607
625
  #
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.
626
+ # Note: Joining or eager loading such associations is not possible because
627
+ # those operations happen before instance creation. Such associations
628
+ # _can_ be preloaded, but doing so will perform N+1 queries because there
629
+ # will be a different scope for each record (similar to preloading
630
+ # polymorphic scopes).
610
631
  #
611
632
  # == Association callbacks
612
633
  #
@@ -614,22 +635,31 @@ module ActiveRecord
614
635
  # you can also define callbacks that get triggered when you add an object to or remove an
615
636
  # object from an association collection.
616
637
  #
617
- # class Project
618
- # has_and_belongs_to_many :developers, after_add: :evaluate_velocity
638
+ # class Firm < ActiveRecord::Base
639
+ # has_many :clients,
640
+ # dependent: :destroy,
641
+ # after_add: :congratulate_client,
642
+ # after_remove: :log_after_remove
643
+ #
644
+ # def congratulate_client(record)
645
+ # # ...
646
+ # end
619
647
  #
620
- # def evaluate_velocity(developer)
621
- # ...
648
+ # def log_after_remove(record)
649
+ # # ...
622
650
  # end
623
651
  # end
624
652
  #
625
653
  # It's possible to stack callbacks by passing them as an array. Example:
626
654
  #
627
- # class Project
628
- # has_and_belongs_to_many :developers,
629
- # after_add: [:evaluate_velocity, Proc.new { |p, d| p.shipping_date = Time.now}]
655
+ # class Firm < ActiveRecord::Base
656
+ # has_many :clients,
657
+ # dependent: :destroy,
658
+ # after_add: [:congratulate_client, -> (firm, record) { firm.log << "after_adding#{record.id}" }],
659
+ # after_remove: :log_after_remove
630
660
  # end
631
661
  #
632
- # Possible callbacks are: +before_add+, +after_add+, +before_remove+ and +after_remove+.
662
+ # Possible callbacks are: +before_add+, +after_add+, +before_remove+, and +after_remove+.
633
663
  #
634
664
  # If any of the +before_add+ callbacks throw an exception, the object will not be
635
665
  # added to the collection.
@@ -637,6 +667,18 @@ module ActiveRecord
637
667
  # Similarly, if any of the +before_remove+ callbacks throw an exception, the object
638
668
  # will not be removed from the collection.
639
669
  #
670
+ # Note: To trigger remove callbacks, you must use +destroy+ / +destroy_all+ methods. For example:
671
+ #
672
+ # * <tt>firm.clients.destroy(client)</tt>
673
+ # * <tt>firm.clients.destroy(*clients)</tt>
674
+ # * <tt>firm.clients.destroy_all</tt>
675
+ #
676
+ # +delete+ / +delete_all+ methods like the following do *not* trigger remove callbacks:
677
+ #
678
+ # * <tt>firm.clients.delete(client)</tt>
679
+ # * <tt>firm.clients.delete(*clients)</tt>
680
+ # * <tt>firm.clients.delete_all</tt>
681
+ #
640
682
  # == Association extensions
641
683
  #
642
684
  # The proxy objects that control the access to associations can be extended through anonymous
@@ -780,9 +822,10 @@ module ActiveRecord
780
822
  # inverse detection only works on #has_many, #has_one, and
781
823
  # #belongs_to associations.
782
824
  #
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.
825
+ # <tt>:foreign_key</tt> and <tt>:through</tt> options on the associations
826
+ # will also prevent the association's inverse from being found automatically,
827
+ # as will a custom scopes in some cases. See further details in the
828
+ # {Active Record Associations guide}[https://guides.rubyonrails.org/association_basics.html#bi-directional-associations].
786
829
  #
787
830
  # The automatic guessing of the inverse association uses a heuristic based
788
831
  # on the name of the class, so it may not work for all associations,
@@ -1020,45 +1063,45 @@ module ActiveRecord
1020
1063
  # Indexes are appended for any more successive uses of the table name.
1021
1064
  #
1022
1065
  # Post.joins(:comments)
1023
- # # => SELECT ... FROM posts INNER JOIN comments ON ...
1066
+ # # SELECT ... FROM posts INNER JOIN comments ON ...
1024
1067
  # Post.joins(:special_comments) # STI
1025
- # # => SELECT ... FROM posts INNER JOIN comments ON ... AND comments.type = 'SpecialComment'
1068
+ # # SELECT ... FROM posts INNER JOIN comments ON ... AND comments.type = 'SpecialComment'
1026
1069
  # 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
1070
+ # # SELECT ... FROM posts INNER JOIN comments ON ... INNER JOIN comments special_comments_posts
1028
1071
  #
1029
1072
  # Acts as tree example:
1030
1073
  #
1031
1074
  # TreeMixin.joins(:children)
1032
- # # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
1075
+ # # SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
1033
1076
  # TreeMixin.joins(children: :parent)
1034
- # # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
1035
- # INNER JOIN parents_mixins ...
1077
+ # # SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
1078
+ # # INNER JOIN parents_mixins ...
1036
1079
  # 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
1080
+ # # SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
1081
+ # # INNER JOIN parents_mixins ...
1082
+ # # INNER JOIN mixins childrens_mixins_2
1040
1083
  #
1041
1084
  # Has and Belongs to Many join tables use the same idea, but add a <tt>_join</tt> suffix:
1042
1085
  #
1043
1086
  # Post.joins(:categories)
1044
- # # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
1087
+ # # SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
1045
1088
  # 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
1089
+ # # SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
1090
+ # # INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
1048
1091
  # 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
1092
+ # # SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
1093
+ # # INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
1094
+ # # INNER JOIN categories_posts categories_posts_join INNER JOIN categories categories_posts_2
1052
1095
  #
1053
1096
  # If you wish to specify your own custom joins using ActiveRecord::QueryMethods#joins method, those table
1054
1097
  # names will take precedence over the eager associations:
1055
1098
  #
1056
1099
  # Post.joins(:comments).joins("inner join comments ...")
1057
- # # => SELECT ... FROM posts INNER JOIN comments_posts ON ... INNER JOIN comments ...
1100
+ # # SELECT ... FROM posts INNER JOIN comments_posts ON ... INNER JOIN comments ...
1058
1101
  # 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 ...
1102
+ # # SELECT ... FROM posts INNER JOIN comments comments_posts ON ...
1103
+ # # INNER JOIN comments special_comments_posts ...
1104
+ # # INNER JOIN comments ...
1062
1105
  #
1063
1106
  # Table aliases are automatically truncated according to the maximum length of table identifiers
1064
1107
  # according to the specific database.
@@ -1139,7 +1182,8 @@ module ActiveRecord
1139
1182
  # belongs_to :dungeon, inverse_of: :evil_wizard
1140
1183
  # end
1141
1184
  #
1142
- # For more information, see the documentation for the +:inverse_of+ option.
1185
+ # For more information, see the documentation for the +:inverse_of+ option and the
1186
+ # {Active Record Associations guide}[https://guides.rubyonrails.org/association_basics.html#bi-directional-associations].
1143
1187
  #
1144
1188
  # == Deleting from associations
1145
1189
  #
@@ -1161,7 +1205,7 @@ module ActiveRecord
1161
1205
  # specific association types. When no option is given, the behavior is to do nothing
1162
1206
  # with the associated records when destroying a record.
1163
1207
  #
1164
- # Note that <tt>:dependent</tt> is implemented using Rails' callback
1208
+ # Note that <tt>:dependent</tt> is implemented using \Rails' callback
1165
1209
  # system, which works by processing callbacks in order. Therefore, other
1166
1210
  # callbacks declared either before or after the <tt>:dependent</tt> option
1167
1211
  # can affect what it does.
@@ -1232,15 +1276,15 @@ module ActiveRecord
1232
1276
  # +collection+ is a placeholder for the symbol passed as the +name+ argument, so
1233
1277
  # <tt>has_many :clients</tt> would add among others <tt>clients.empty?</tt>.
1234
1278
  #
1235
- # [collection]
1279
+ # [<tt>collection</tt>]
1236
1280
  # Returns a Relation of all the associated objects.
1237
1281
  # An empty Relation is returned if none are found.
1238
- # [collection<<(object, ...)]
1282
+ # [<tt>collection<<(object, ...)</tt>]
1239
1283
  # Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
1240
1284
  # Note that this operation instantly fires update SQL without waiting for the save or update call on the
1241
1285
  # parent object, unless the parent object is a new record.
1242
1286
  # This will also run validations and callbacks of associated object(s).
1243
- # [collection.delete(object, ...)]
1287
+ # [<tt>collection.delete(object, ...)</tt>]
1244
1288
  # Removes one or more objects from the collection by setting their foreign keys to +NULL+.
1245
1289
  # Objects will be in addition destroyed if they're associated with <tt>dependent: :destroy</tt>,
1246
1290
  # and deleted if they're associated with <tt>dependent: :delete_all</tt>.
@@ -1248,75 +1292,84 @@ module ActiveRecord
1248
1292
  # If the <tt>:through</tt> option is used, then the join records are deleted (rather than
1249
1293
  # nullified) by default, but you can specify <tt>dependent: :destroy</tt> or
1250
1294
  # <tt>dependent: :nullify</tt> to override this.
1251
- # [collection.destroy(object, ...)]
1295
+ # [<tt>collection.destroy(object, ...)</tt>]
1252
1296
  # Removes one or more objects from the collection by running <tt>destroy</tt> on
1253
1297
  # each record, regardless of any dependent option, ensuring callbacks are run.
1254
1298
  #
1255
1299
  # If the <tt>:through</tt> option is used, then the join records are destroyed
1256
1300
  # instead, not the objects themselves.
1257
- # [collection=objects]
1301
+ # [<tt>collection=objects</tt>]
1258
1302
  # Replaces the collections content by deleting and adding objects as appropriate. If the <tt>:through</tt>
1259
1303
  # option is true callbacks in the join models are triggered except destroy callbacks, since deletion is
1260
1304
  # direct by default. You can specify <tt>dependent: :destroy</tt> or
1261
1305
  # <tt>dependent: :nullify</tt> to override this.
1262
- # [collection_singular_ids]
1306
+ # [<tt>collection_singular_ids</tt>]
1263
1307
  # Returns an array of the associated objects' ids
1264
- # [collection_singular_ids=ids]
1308
+ # [<tt>collection_singular_ids=ids</tt>]
1265
1309
  # Replace the collection with the objects identified by the primary keys in +ids+. This
1266
1310
  # method loads the models and calls <tt>collection=</tt>. See above.
1267
- # [collection.clear]
1311
+ # [<tt>collection.clear</tt>]
1268
1312
  # Removes every object from the collection. This destroys the associated objects if they
1269
1313
  # are associated with <tt>dependent: :destroy</tt>, deletes them directly from the
1270
1314
  # database if <tt>dependent: :delete_all</tt>, otherwise sets their foreign keys to +NULL+.
1271
1315
  # If the <tt>:through</tt> option is true no destroy callbacks are invoked on the join models.
1272
1316
  # Join models are directly deleted.
1273
- # [collection.empty?]
1317
+ # [<tt>collection.empty?</tt>]
1274
1318
  # Returns +true+ if there are no associated objects.
1275
- # [collection.size]
1319
+ # [<tt>collection.size</tt>]
1276
1320
  # Returns the number of associated objects.
1277
- # [collection.find(...)]
1321
+ # [<tt>collection.find(...)</tt>]
1278
1322
  # Finds an associated object according to the same rules as ActiveRecord::FinderMethods#find.
1279
- # [collection.exists?(...)]
1323
+ # [<tt>collection.exists?(...)</tt>]
1280
1324
  # Checks whether an associated object with the given conditions exists.
1281
1325
  # Uses the same rules as ActiveRecord::FinderMethods#exists?.
1282
- # [collection.build(attributes = {}, ...)]
1326
+ # [<tt>collection.build(attributes = {}, ...)</tt>]
1283
1327
  # Returns one or more new objects of the collection type that have been instantiated
1284
1328
  # with +attributes+ and linked to this object through a foreign key, but have not yet
1285
1329
  # been saved.
1286
- # [collection.create(attributes = {})]
1330
+ # [<tt>collection.create(attributes = {})</tt>]
1287
1331
  # Returns a new object of the collection type that has been instantiated
1288
1332
  # with +attributes+, linked to this object through a foreign key, and that has already
1289
1333
  # been saved (if it passed the validation). *Note*: This only works if the base model
1290
1334
  # already exists in the DB, not if it is a new (unsaved) record!
1291
- # [collection.create!(attributes = {})]
1335
+ # [<tt>collection.create!(attributes = {})</tt>]
1292
1336
  # Does the same as <tt>collection.create</tt>, but raises ActiveRecord::RecordInvalid
1293
1337
  # if the record is invalid.
1294
- # [collection.reload]
1338
+ # [<tt>collection.reload</tt>]
1295
1339
  # Returns a Relation of all of the associated objects, forcing a database read.
1296
1340
  # An empty Relation is returned if none are found.
1297
1341
  #
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>
1342
+ # ==== Example
1343
+ #
1344
+ # class Firm < ActiveRecord::Base
1345
+ # has_many :clients
1346
+ # end
1347
+ #
1348
+ # Declaring <tt>has_many :clients</tt> adds the following methods (and more):
1349
+ #
1350
+ # firm = Firm.find(2)
1351
+ # client = Client.find(6)
1352
+ #
1353
+ # firm.clients # similar to Client.where(firm_id: 2)
1354
+ # firm.clients << client
1355
+ # firm.clients.delete(client)
1356
+ # firm.clients.destroy(client)
1357
+ # firm.clients = [client]
1358
+ # firm.client_ids
1359
+ # firm.client_ids = [6]
1360
+ # firm.clients.clear
1361
+ # firm.clients.empty? # similar to firm.clients.size == 0
1362
+ # firm.clients.size # similar to Client.count "firm_id = 2"
1363
+ # firm.clients.find # similar to Client.where(firm_id: 2).find(6)
1364
+ # firm.clients.exists?(name: 'ACME') # similar to Client.exists?(name: 'ACME', firm_id: 2)
1365
+ # firm.clients.build # similar to Client.new(firm_id: 2)
1366
+ # firm.clients.create # similar to Client.create(firm_id: 2)
1367
+ # firm.clients.create! # similar to Client.create!(firm_id: 2)
1368
+ # firm.clients.reload
1369
+ #
1317
1370
  # The declaration can also include an +options+ hash to specialize the behavior of the association.
1318
1371
  #
1319
- # === Scopes
1372
+ # ==== Scopes
1320
1373
  #
1321
1374
  # You can pass a second argument +scope+ as a callable (i.e. proc or
1322
1375
  # lambda) to retrieve a specific set of records or customize the generated
@@ -1327,10 +1380,10 @@ module ActiveRecord
1327
1380
  # has_many :employees, -> { joins(:address) }
1328
1381
  # has_many :posts, ->(blog) { where("max_post_length > ?", blog.max_post_length) }
1329
1382
  #
1330
- # === Extensions
1383
+ # ==== Extensions
1331
1384
  #
1332
1385
  # 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
1386
+ # association. This is useful for adding new finders, creators, and other
1334
1387
  # factory-type methods to be used as part of the association.
1335
1388
  #
1336
1389
  # Extension examples:
@@ -1341,31 +1394,31 @@ module ActiveRecord
1341
1394
  # end
1342
1395
  # end
1343
1396
  #
1344
- # === Options
1345
- # [:class_name]
1397
+ # ==== Options
1398
+ # [+:class_name+]
1346
1399
  # Specify the class name of the association. Use it only if that name can't be inferred
1347
1400
  # from the association name. So <tt>has_many :products</tt> will by default be linked
1348
1401
  # to the +Product+ class, but if the real class name is +SpecialProduct+, you'll have to
1349
1402
  # specify it with this option.
1350
- # [:foreign_key]
1403
+ # [+:foreign_key+]
1351
1404
  # Specify the foreign key used for the association. By default this is guessed to be the name
1352
1405
  # of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_many
1353
1406
  # association will use "person_id" as the default <tt>:foreign_key</tt>.
1354
1407
  #
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]
1408
+ # Setting the <tt>:foreign_key</tt> option prevents automatic detection of the association's
1409
+ # inverse, so it is generally a good idea to set the <tt>:inverse_of</tt> option as well.
1410
+ # [+:foreign_type+]
1358
1411
  # Specify the column used to store the associated object's type, if this is a polymorphic
1359
1412
  # association. By default this is guessed to be the name of the polymorphic association
1360
1413
  # specified on "as" option with a "_type" suffix. So a class that defines a
1361
1414
  # <tt>has_many :tags, as: :taggable</tt> association will use "taggable_type" as the
1362
1415
  # default <tt>:foreign_type</tt>.
1363
- # [:primary_key]
1416
+ # [+:primary_key+]
1364
1417
  # Specify the name of the column to use as the primary key for the association. By default this is +id+.
1365
- # [:dependent]
1418
+ # [+:dependent+]
1366
1419
  # Controls what happens to the associated objects when
1367
1420
  # their owner is destroyed. Note that these are implemented as
1368
- # callbacks, and Rails executes callbacks in order. Therefore, other
1421
+ # callbacks, and \Rails executes callbacks in order. Therefore, other
1369
1422
  # similar callbacks may affect the <tt>:dependent</tt> behavior, and the
1370
1423
  # <tt>:dependent</tt> behavior may affect other callbacks.
1371
1424
  #
@@ -1377,7 +1430,7 @@ module ActiveRecord
1377
1430
  # * <tt>:delete_all</tt> causes all the associated objects to be deleted directly from the database (so callbacks will not be executed).
1378
1431
  # * <tt>:nullify</tt> causes the foreign keys to be set to +NULL+. Polymorphic type will also be nullified
1379
1432
  # 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.
1433
+ # * <tt>:restrict_with_exception</tt> causes an ActiveRecord::DeleteRestrictionError exception to be raised if there are any associated records.
1381
1434
  # * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there are any associated objects.
1382
1435
  #
1383
1436
  # If using with the <tt>:through</tt> option, the association on the join model must be
@@ -1389,12 +1442,12 @@ module ActiveRecord
1389
1442
  # <tt>has_many :comments, -> { where published: true }, dependent: :destroy</tt> and <tt>destroy</tt> is
1390
1443
  # called on a post, only published comments are destroyed. This means that any unpublished comments in the
1391
1444
  # database would still contain a foreign key pointing to the now deleted post.
1392
- # [:counter_cache]
1445
+ # [+:counter_cache+]
1393
1446
  # This option can be used to configure a custom named <tt>:counter_cache.</tt> You only need this option,
1394
1447
  # when you customized the name of your <tt>:counter_cache</tt> on the #belongs_to association.
1395
- # [:as]
1448
+ # [+:as+]
1396
1449
  # Specifies a polymorphic interface (See #belongs_to).
1397
- # [:through]
1450
+ # [+:through+]
1398
1451
  # Specifies an association through which to perform the query. This can be any other type
1399
1452
  # of association, including other <tt>:through</tt> associations. Options for <tt>:class_name</tt>,
1400
1453
  # <tt>:primary_key</tt> and <tt>:foreign_key</tt> are ignored, as the association uses the
@@ -1409,19 +1462,24 @@ module ActiveRecord
1409
1462
  # a good idea to set the <tt>:inverse_of</tt> option on the source association on the
1410
1463
  # join model. This allows associated records to be built which will automatically create
1411
1464
  # the appropriate join model records when they are saved. (See the 'Association Join Models'
1412
- # section above.)
1413
- # [:source]
1465
+ # and 'Setting Inverses' sections above.)
1466
+ # [+:disable_joins+]
1467
+ # Specifies whether joins should be skipped for an association. If set to true, two or more queries
1468
+ # will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory
1469
+ # due to database limitations. This option is only applicable on <tt>has_many :through</tt> associations as
1470
+ # +has_many+ alone do not perform a join.
1471
+ # [+:source+]
1414
1472
  # Specifies the source association name used by #has_many <tt>:through</tt> queries.
1415
1473
  # Only use it if the name cannot be inferred from the association.
1416
1474
  # <tt>has_many :subscribers, through: :subscriptions</tt> will look for either <tt>:subscribers</tt> or
1417
1475
  # <tt>:subscriber</tt> on Subscription, unless a <tt>:source</tt> is given.
1418
- # [:source_type]
1476
+ # [+:source_type+]
1419
1477
  # Specifies type of the source association used by #has_many <tt>:through</tt> queries where the source
1420
1478
  # association is a polymorphic #belongs_to.
1421
- # [:validate]
1479
+ # [+:validate+]
1422
1480
  # When set to +true+, validates new objects added to association when saving the parent object. +true+ by default.
1423
1481
  # If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
1424
- # [:autosave]
1482
+ # [+:autosave+]
1425
1483
  # If true, always save the associated objects or destroy them if marked for destruction,
1426
1484
  # when saving the parent object. If false, never save or destroy the associated objects.
1427
1485
  # By default, only save associated objects that are new records. This option is implemented as a
@@ -1430,19 +1488,24 @@ module ActiveRecord
1430
1488
  #
1431
1489
  # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
1432
1490
  # <tt>:autosave</tt> to <tt>true</tt>.
1433
- # [:inverse_of]
1491
+ # [+:inverse_of+]
1434
1492
  # Specifies the name of the #belongs_to association on the associated object
1435
1493
  # that is the inverse of this #has_many association.
1436
1494
  # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1437
- # [:extend]
1495
+ # [+:extend+]
1438
1496
  # Specifies a module or array of modules that will be extended into the association object returned.
1439
1497
  # Useful for defining methods on associations, especially when they should be shared between multiple
1440
1498
  # association objects.
1441
- # [:strict_loading]
1442
- # Enforces strict loading every time the associated record is loaded through this association.
1443
- # [:ensuring_owner_was]
1499
+ # [+:strict_loading+]
1500
+ # When set to +true+, enforces strict loading every time the associated record is loaded through this
1501
+ # association.
1502
+ # [+:ensuring_owner_was+]
1444
1503
  # Specifies an instance method to be called on the owner. The method must return true in order for the
1445
1504
  # associated records to be deleted in a background job.
1505
+ # [+:query_constraints+]
1506
+ # Serves as a composite foreign key. Defines the list of columns to be used to query the associated object.
1507
+ # This is an optional option. By default Rails will attempt to derive the value automatically.
1508
+ # When the value is set the Array size must match associated model's primary key or +query_constraints+ size.
1446
1509
  #
1447
1510
  # Option examples:
1448
1511
  # has_many :comments, -> { order("posted_on") }
@@ -1453,7 +1516,9 @@ module ActiveRecord
1453
1516
  # has_many :tags, as: :taggable
1454
1517
  # has_many :reports, -> { readonly }
1455
1518
  # has_many :subscribers, through: :subscriptions, source: :user
1519
+ # has_many :subscribers, through: :subscriptions, disable_joins: true
1456
1520
  # has_many :comments, strict_loading: true
1521
+ # has_many :comments, query_constraints: [:blog_id, :post_id]
1457
1522
  def has_many(name, scope = nil, **options, &extension)
1458
1523
  reflection = Builder::HasMany.build(self, name, scope, options, &extension)
1459
1524
  Reflection.add_reflection self, name, reflection
@@ -1469,37 +1534,48 @@ module ActiveRecord
1469
1534
  # +association+ is a placeholder for the symbol passed as the +name+ argument, so
1470
1535
  # <tt>has_one :manager</tt> would add among others <tt>manager.nil?</tt>.
1471
1536
  #
1472
- # [association]
1537
+ # [<tt>association</tt>]
1473
1538
  # Returns the associated object. +nil+ is returned if none is found.
1474
- # [association=(associate)]
1539
+ # [<tt>association=(associate)</tt>]
1475
1540
  # Assigns the associate object, extracts the primary key, sets it as the foreign key,
1476
1541
  # and saves the associate object. To avoid database inconsistencies, permanently deletes an existing
1477
1542
  # associated object when assigning a new one, even if the new one isn't saved to database.
1478
- # [build_association(attributes = {})]
1543
+ # [<tt>build_association(attributes = {})</tt>]
1479
1544
  # Returns a new object of the associated type that has been instantiated
1480
1545
  # with +attributes+ and linked to this object through a foreign key, but has not
1481
1546
  # yet been saved.
1482
- # [create_association(attributes = {})]
1547
+ # [<tt>create_association(attributes = {})</tt>]
1483
1548
  # Returns a new object of the associated type that has been instantiated
1484
1549
  # with +attributes+, linked to this object through a foreign key, and that
1485
1550
  # has already been saved (if it passed the validation).
1486
- # [create_association!(attributes = {})]
1551
+ # [<tt>create_association!(attributes = {})</tt>]
1487
1552
  # Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
1488
1553
  # if the record is invalid.
1489
- # [reload_association]
1554
+ # [<tt>reload_association</tt>]
1490
1555
  # Returns the associated object, forcing a database read.
1556
+ # [<tt>reset_association</tt>]
1557
+ # Unloads the associated object. The next access will query it from the database.
1558
+ #
1559
+ # ==== Example
1560
+ #
1561
+ # class Account < ActiveRecord::Base
1562
+ # has_one :beneficiary
1563
+ # end
1564
+ #
1565
+ # Declaring <tt>has_one :beneficiary</tt> adds the following methods (and more):
1491
1566
  #
1492
- # === Example
1567
+ # account = Account.find(5)
1568
+ # beneficiary = Beneficiary.find(8)
1493
1569
  #
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>
1570
+ # account.beneficiary # similar to Beneficiary.find_by(account_id: 5)
1571
+ # account.beneficiary = beneficiary # similar to beneficiary.update(account_id: 5)
1572
+ # account.build_beneficiary # similar to Beneficiary.new(account_id: 5)
1573
+ # account.create_beneficiary # similar to Beneficiary.create(account_id: 5)
1574
+ # account.create_beneficiary! # similar to Beneficiary.create!(account_id: 5)
1575
+ # account.reload_beneficiary
1576
+ # account.reset_beneficiary
1501
1577
  #
1502
- # === Scopes
1578
+ # ==== Scopes
1503
1579
  #
1504
1580
  # You can pass a second argument +scope+ as a callable (i.e. proc or
1505
1581
  # lambda) to retrieve a specific record or customize the generated query
@@ -1510,16 +1586,16 @@ module ActiveRecord
1510
1586
  # has_one :employer, -> { joins(:company) }
1511
1587
  # has_one :latest_post, ->(blog) { where("created_at > ?", blog.enabled_at) }
1512
1588
  #
1513
- # === Options
1589
+ # ==== Options
1514
1590
  #
1515
1591
  # The declaration can also include an +options+ hash to specialize the behavior of the association.
1516
1592
  #
1517
1593
  # Options are:
1518
- # [:class_name]
1594
+ # [+:class_name+]
1519
1595
  # Specify the class name of the association. Use it only if that name can't be inferred
1520
1596
  # from the association name. So <tt>has_one :manager</tt> will by default be linked to the Manager class, but
1521
1597
  # if the real class name is Person, you'll have to specify it with this option.
1522
- # [:dependent]
1598
+ # [+:dependent+]
1523
1599
  # Controls what happens to the associated object when
1524
1600
  # its owner is destroyed:
1525
1601
  #
@@ -1531,66 +1607,89 @@ module ActiveRecord
1531
1607
  # * <tt>:delete</tt> causes the associated object to be deleted directly from the database (so callbacks will not execute)
1532
1608
  # * <tt>:nullify</tt> causes the foreign key to be set to +NULL+. Polymorphic type column is also nullified
1533
1609
  # 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
1610
+ # * <tt>:restrict_with_exception</tt> causes an ActiveRecord::DeleteRestrictionError exception to be raised if there is an associated record
1535
1611
  # * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there is an associated object
1536
1612
  #
1537
1613
  # Note that <tt>:dependent</tt> option is ignored when using <tt>:through</tt> option.
1538
- # [:foreign_key]
1614
+ # [+:foreign_key+]
1539
1615
  # Specify the foreign key used for the association. By default this is guessed to be the name
1540
1616
  # of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_one association
1541
1617
  # will use "person_id" as the default <tt>:foreign_key</tt>.
1542
1618
  #
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]
1619
+ # Setting the <tt>:foreign_key</tt> option prevents automatic detection of the association's
1620
+ # inverse, so it is generally a good idea to set the <tt>:inverse_of</tt> option as well.
1621
+ # [+:foreign_type+]
1546
1622
  # Specify the column used to store the associated object's type, if this is a polymorphic
1547
1623
  # association. By default this is guessed to be the name of the polymorphic association
1548
1624
  # specified on "as" option with a "_type" suffix. So a class that defines a
1549
1625
  # <tt>has_one :tag, as: :taggable</tt> association will use "taggable_type" as the
1550
1626
  # default <tt>:foreign_type</tt>.
1551
- # [:primary_key]
1627
+ # [+:primary_key+]
1552
1628
  # Specify the method that returns the primary key used for the association. By default this is +id+.
1553
- # [:as]
1629
+ # [+:as+]
1554
1630
  # Specifies a polymorphic interface (See #belongs_to).
1555
- # [:through]
1631
+ # [+:through+]
1556
1632
  # Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt>,
1557
1633
  # <tt>:primary_key</tt>, and <tt>:foreign_key</tt> are ignored, as the association uses the
1558
1634
  # source reflection. You can only use a <tt>:through</tt> query through a #has_one
1559
1635
  # or #belongs_to association on the join model.
1560
1636
  #
1637
+ # If the association on the join model is a #belongs_to, the collection can be modified
1638
+ # and the records on the <tt>:through</tt> model will be automatically created and removed
1639
+ # as appropriate. Otherwise, the collection is read-only, so you should manipulate the
1640
+ # <tt>:through</tt> association directly.
1641
+ #
1561
1642
  # 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]
1643
+ # a good idea to set the <tt>:inverse_of</tt> option on the source association on the
1644
+ # join model. This allows associated records to be built which will automatically create
1645
+ # the appropriate join model records when they are saved. (See the 'Association Join Models'
1646
+ # and 'Setting Inverses' sections above.)
1647
+ # [+:disable_joins+]
1648
+ # Specifies whether joins should be skipped for an association. If set to true, two or more queries
1649
+ # will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory
1650
+ # due to database limitations. This option is only applicable on <tt>has_one :through</tt> associations as
1651
+ # +has_one+ alone does not perform a join.
1652
+ # [+:source+]
1564
1653
  # Specifies the source association name used by #has_one <tt>:through</tt> queries.
1565
1654
  # Only use it if the name cannot be inferred from the association.
1566
1655
  # <tt>has_one :favorite, through: :favorites</tt> will look for a
1567
1656
  # <tt>:favorite</tt> on Favorite, unless a <tt>:source</tt> is given.
1568
- # [:source_type]
1657
+ # [+:source_type+]
1569
1658
  # Specifies type of the source association used by #has_one <tt>:through</tt> queries where the source
1570
1659
  # association is a polymorphic #belongs_to.
1571
- # [:validate]
1660
+ # [+:validate+]
1572
1661
  # When set to +true+, validates new objects added to association when saving the parent object. +false+ by default.
1573
1662
  # If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
1574
- # [:autosave]
1663
+ # [+:autosave+]
1575
1664
  # If true, always save the associated object or destroy it if marked for destruction,
1576
1665
  # when saving the parent object. If false, never save or destroy the associated object.
1577
1666
  # By default, only save the associated object if it's a new record.
1578
1667
  #
1579
1668
  # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
1580
1669
  # <tt>:autosave</tt> to <tt>true</tt>.
1581
- # [:inverse_of]
1670
+ # [+:touch+]
1671
+ # If true, the associated object will be touched (the +updated_at+ / +updated_on+ attributes set to current time)
1672
+ # when this record is either saved or destroyed. If you specify a symbol, that attribute
1673
+ # will be updated with the current time in addition to the +updated_at+ / +updated_on+ attribute.
1674
+ # Please note that no validation will be performed when touching, and only the +after_touch+,
1675
+ # +after_commit+, and +after_rollback+ callbacks will be executed.
1676
+ # [+:inverse_of+]
1582
1677
  # Specifies the name of the #belongs_to association on the associated object
1583
1678
  # that is the inverse of this #has_one association.
1584
1679
  # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1585
- # [:required]
1680
+ # [+:required+]
1586
1681
  # When set to +true+, the association will also have its presence validated.
1587
1682
  # This will validate the association itself, not the id. You can use
1588
1683
  # +:inverse_of+ to avoid an extra query during validation.
1589
- # [:strict_loading]
1684
+ # [+:strict_loading+]
1590
1685
  # Enforces strict loading every time the associated record is loaded through this association.
1591
- # [:ensuring_owner_was]
1686
+ # [+:ensuring_owner_was+]
1592
1687
  # Specifies an instance method to be called on the owner. The method must return true in order for the
1593
1688
  # associated records to be deleted in a background job.
1689
+ # [+:query_constraints+]
1690
+ # Serves as a composite foreign key. Defines the list of columns to be used to query the associated object.
1691
+ # This is an optional option. By default Rails will attempt to derive the value automatically.
1692
+ # When the value is set the Array size must match associated model's primary key or +query_constraints+ size.
1594
1693
  #
1595
1694
  # Option examples:
1596
1695
  # has_one :credit_card, dependent: :destroy # destroys the associated credit card
@@ -1601,9 +1700,11 @@ module ActiveRecord
1601
1700
  # has_one :attachment, as: :attachable
1602
1701
  # has_one :boss, -> { readonly }
1603
1702
  # has_one :club, through: :membership
1703
+ # has_one :club, through: :membership, disable_joins: true
1604
1704
  # has_one :primary_address, -> { where(primary: true) }, through: :addressables, source: :addressable
1605
1705
  # has_one :credit_card, required: true
1606
1706
  # has_one :credit_card, strict_loading: true
1707
+ # has_one :employment_record_book, query_constraints: [:organization_id, :employee_id]
1607
1708
  def has_one(name, scope = nil, **options)
1608
1709
  reflection = Builder::HasOne.build(self, name, scope, options)
1609
1710
  Reflection.add_reflection self, name, reflection
@@ -1620,36 +1721,52 @@ module ActiveRecord
1620
1721
  # +association+ is a placeholder for the symbol passed as the +name+ argument, so
1621
1722
  # <tt>belongs_to :author</tt> would add among others <tt>author.nil?</tt>.
1622
1723
  #
1623
- # [association]
1724
+ # [<tt>association</tt>]
1624
1725
  # Returns the associated object. +nil+ is returned if none is found.
1625
- # [association=(associate)]
1726
+ # [<tt>association=(associate)</tt>]
1626
1727
  # Assigns the associate object, extracts the primary key, and sets it as the foreign key.
1627
1728
  # No modification or deletion of existing records takes place.
1628
- # [build_association(attributes = {})]
1729
+ # [<tt>build_association(attributes = {})</tt>]
1629
1730
  # Returns a new object of the associated type that has been instantiated
1630
1731
  # with +attributes+ and linked to this object through a foreign key, but has not yet been saved.
1631
- # [create_association(attributes = {})]
1732
+ # [<tt>create_association(attributes = {})</tt>]
1632
1733
  # Returns a new object of the associated type that has been instantiated
1633
1734
  # with +attributes+, linked to this object through a foreign key, and that
1634
1735
  # has already been saved (if it passed the validation).
1635
- # [create_association!(attributes = {})]
1736
+ # [<tt>create_association!(attributes = {})</tt>]
1636
1737
  # Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
1637
1738
  # if the record is invalid.
1638
- # [reload_association]
1739
+ # [<tt>reload_association</tt>]
1639
1740
  # Returns the associated object, forcing a database read.
1741
+ # [<tt>reset_association</tt>]
1742
+ # Unloads the associated object. The next access will query it from the database.
1743
+ # [<tt>association_changed?</tt>]
1744
+ # Returns true if a new associate object has been assigned and the next save will update the foreign key.
1745
+ # [<tt>association_previously_changed?</tt>]
1746
+ # Returns true if the previous save updated the association to reference a new associate object.
1640
1747
  #
1641
- # === Example
1748
+ # ==== Example
1642
1749
  #
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.
1750
+ # class Post < ActiveRecord::Base
1751
+ # belongs_to :author
1752
+ # end
1753
+ #
1754
+ # Declaring <tt>belongs_to :author</tt> adds the following methods (and more):
1651
1755
  #
1652
- # === Scopes
1756
+ # post = Post.find(7)
1757
+ # author = Author.find(19)
1758
+ #
1759
+ # post.author # similar to Author.find(post.author_id)
1760
+ # post.author = author # similar to post.author_id = author.id
1761
+ # post.build_author # similar to post.author = Author.new
1762
+ # post.create_author # similar to post.author = Author.new; post.author.save; post.author
1763
+ # post.create_author! # similar to post.author = Author.new; post.author.save!; post.author
1764
+ # post.reload_author
1765
+ # post.reset_author
1766
+ # post.author_changed?
1767
+ # post.author_previously_changed?
1768
+ #
1769
+ # ==== Scopes
1653
1770
  #
1654
1771
  # You can pass a second argument +scope+ as a callable (i.e. proc or
1655
1772
  # lambda) to retrieve a specific record or customize the generated query
@@ -1660,37 +1777,39 @@ module ActiveRecord
1660
1777
  # belongs_to :user, -> { joins(:friends) }
1661
1778
  # belongs_to :level, ->(game) { where("game_level > ?", game.current_level) }
1662
1779
  #
1663
- # === Options
1780
+ # ==== Options
1664
1781
  #
1665
- # [:class_name]
1782
+ # The declaration can also include an +options+ hash to specialize the behavior of the association.
1783
+ #
1784
+ # [+:class_name+]
1666
1785
  # Specify the class name of the association. Use it only if that name can't be inferred
1667
1786
  # from the association name. So <tt>belongs_to :author</tt> will by default be linked to the Author class, but
1668
1787
  # if the real class name is Person, you'll have to specify it with this option.
1669
- # [:foreign_key]
1788
+ # [+:foreign_key+]
1670
1789
  # Specify the foreign key used for the association. By default this is guessed to be the name
1671
1790
  # of the association with an "_id" suffix. So a class that defines a <tt>belongs_to :person</tt>
1672
1791
  # association will use "person_id" as the default <tt>:foreign_key</tt>. Similarly,
1673
1792
  # <tt>belongs_to :favorite_person, class_name: "Person"</tt> will use a foreign key
1674
1793
  # of "favorite_person_id".
1675
1794
  #
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]
1795
+ # Setting the <tt>:foreign_key</tt> option prevents automatic detection of the association's
1796
+ # inverse, so it is generally a good idea to set the <tt>:inverse_of</tt> option as well.
1797
+ # [+:foreign_type+]
1679
1798
  # Specify the column used to store the associated object's type, if this is a polymorphic
1680
1799
  # association. By default this is guessed to be the name of the association with a "_type"
1681
1800
  # suffix. So a class that defines a <tt>belongs_to :taggable, polymorphic: true</tt>
1682
1801
  # association will use "taggable_type" as the default <tt>:foreign_type</tt>.
1683
- # [:primary_key]
1802
+ # [+:primary_key+]
1684
1803
  # Specify the method that returns the primary key of associated object used for the association.
1685
1804
  # By default this is +id+.
1686
- # [:dependent]
1805
+ # [+:dependent+]
1687
1806
  # If set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to
1688
1807
  # <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method. If set to
1689
1808
  # <tt>:destroy_async</tt>, the associated object is scheduled to be destroyed in a background job.
1690
1809
  # This option should not be specified when #belongs_to is used in conjunction with
1691
1810
  # a #has_many relationship on another class because of the potential to leave
1692
1811
  # orphaned records behind.
1693
- # [:counter_cache]
1812
+ # [+:counter_cache+]
1694
1813
  # Caches the number of belonging objects on the associate class through the use of CounterCache::ClassMethods#increment_counter
1695
1814
  # and CounterCache::ClassMethods#decrement_counter. The counter cache is incremented when an object of this
1696
1815
  # class is created and decremented when it's destroyed. This requires that a column
@@ -1702,14 +1821,14 @@ module ActiveRecord
1702
1821
  # option (e.g., <tt>counter_cache: :my_custom_counter</tt>.)
1703
1822
  # Note: Specifying a counter cache will add it to that model's list of readonly attributes
1704
1823
  # using +attr_readonly+.
1705
- # [:polymorphic]
1824
+ # [+:polymorphic+]
1706
1825
  # Specify this association is a polymorphic association by passing +true+.
1707
1826
  # Note: If you've enabled the counter cache, then you may want to add the counter cache attribute
1708
1827
  # to the +attr_readonly+ list in the associated classes (e.g. <tt>class Post; attr_readonly :comments_count; end</tt>).
1709
- # [:validate]
1828
+ # [+:validate+]
1710
1829
  # When set to +true+, validates new objects added to association when saving the parent object. +false+ by default.
1711
1830
  # If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
1712
- # [:autosave]
1831
+ # [+:autosave+]
1713
1832
  # If true, always save the associated object or destroy it if marked for destruction, when
1714
1833
  # saving the parent object.
1715
1834
  # If false, never save or destroy the associated object.
@@ -1717,32 +1836,37 @@ module ActiveRecord
1717
1836
  #
1718
1837
  # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for
1719
1838
  # 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)
1839
+ # [+:touch+]
1840
+ # If true, the associated object will be touched (the +updated_at+ / +updated_on+ attributes set to current time)
1722
1841
  # 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]
1842
+ # will be updated with the current time in addition to the +updated_at+ / +updated_on+ attribute.
1843
+ # Please note that no validation will be performed when touching, and only the +after_touch+,
1844
+ # +after_commit+, and +after_rollback+ callbacks will be executed.
1845
+ # [+:inverse_of+]
1727
1846
  # Specifies the name of the #has_one or #has_many association on the associated
1728
1847
  # object that is the inverse of this #belongs_to association.
1729
1848
  # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1730
- # [:optional]
1849
+ # [+:optional+]
1731
1850
  # When set to +true+, the association will not have its presence validated.
1732
- # [:required]
1851
+ # [+:required+]
1733
1852
  # When set to +true+, the association will also have its presence validated.
1734
1853
  # This will validate the association itself, not the id. You can use
1735
1854
  # +:inverse_of+ to avoid an extra query during validation.
1736
1855
  # NOTE: <tt>required</tt> is set to <tt>true</tt> by default and is deprecated. If
1737
1856
  # you don't want to have association presence validated, use <tt>optional: true</tt>.
1738
- # [:default]
1857
+ # [+:default+]
1739
1858
  # Provide a callable (i.e. proc or lambda) to specify that the association should
1740
1859
  # be initialized with a particular record before validation.
1741
- # [:strict_loading]
1860
+ # Please note that callable won't be executed if the record exists.
1861
+ # [+:strict_loading+]
1742
1862
  # Enforces strict loading every time the associated record is loaded through this association.
1743
- # [:ensuring_owner_was]
1863
+ # [+:ensuring_owner_was+]
1744
1864
  # Specifies an instance method to be called on the owner. The method must return true in order for the
1745
1865
  # associated records to be deleted in a background job.
1866
+ # [+:query_constraints+]
1867
+ # Serves as a composite foreign key. Defines the list of columns to be used to query the associated object.
1868
+ # This is an optional option. By default Rails will attempt to derive the value automatically.
1869
+ # When the value is set the Array size must match associated model's primary key or +query_constraints+ size.
1746
1870
  #
1747
1871
  # Option examples:
1748
1872
  # belongs_to :firm, foreign_key: "client_of"
@@ -1758,6 +1882,7 @@ module ActiveRecord
1758
1882
  # belongs_to :user, optional: true
1759
1883
  # belongs_to :account, default: -> { company.account }
1760
1884
  # belongs_to :account, strict_loading: true
1885
+ # belong_to :note, query_constraints: [:organization_id, :note_id]
1761
1886
  def belongs_to(name, scope = nil, **options)
1762
1887
  reflection = Builder::BelongsTo.build(self, name, scope, options)
1763
1888
  Reflection.add_reflection self, name, reflection
@@ -1780,7 +1905,7 @@ module ActiveRecord
1780
1905
  # The join table should not have a primary key or a model associated with it. You must manually generate the
1781
1906
  # join table with a migration such as this:
1782
1907
  #
1783
- # class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration[6.0]
1908
+ # class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration[7.1]
1784
1909
  # def change
1785
1910
  # create_join_table :developers, :projects
1786
1911
  # end
@@ -1795,71 +1920,80 @@ module ActiveRecord
1795
1920
  # +collection+ is a placeholder for the symbol passed as the +name+ argument, so
1796
1921
  # <tt>has_and_belongs_to_many :categories</tt> would add among others <tt>categories.empty?</tt>.
1797
1922
  #
1798
- # [collection]
1923
+ # [<tt>collection</tt>]
1799
1924
  # Returns a Relation of all the associated objects.
1800
1925
  # An empty Relation is returned if none are found.
1801
- # [collection<<(object, ...)]
1926
+ # [<tt>collection<<(object, ...)</tt>]
1802
1927
  # Adds one or more objects to the collection by creating associations in the join table
1803
1928
  # (<tt>collection.push</tt> and <tt>collection.concat</tt> are aliases to this method).
1804
1929
  # Note that this operation instantly fires update SQL without waiting for the save or update call on the
1805
1930
  # parent object, unless the parent object is a new record.
1806
- # [collection.delete(object, ...)]
1931
+ # [<tt>collection.delete(object, ...)</tt>]
1807
1932
  # Removes one or more objects from the collection by removing their associations from the join table.
1808
1933
  # This does not destroy the objects.
1809
- # [collection.destroy(object, ...)]
1934
+ # [<tt>collection.destroy(object, ...)</tt>]
1810
1935
  # Removes one or more objects from the collection by running destroy on each association in the join table, overriding any dependent option.
1811
1936
  # This does not destroy the objects.
1812
- # [collection=objects]
1937
+ # [<tt>collection=objects</tt>]
1813
1938
  # Replaces the collection's content by deleting and adding objects as appropriate.
1814
- # [collection_singular_ids]
1939
+ # [<tt>collection_singular_ids</tt>]
1815
1940
  # Returns an array of the associated objects' ids.
1816
- # [collection_singular_ids=ids]
1941
+ # [<tt>collection_singular_ids=ids</tt>]
1817
1942
  # Replace the collection by the objects identified by the primary keys in +ids+.
1818
- # [collection.clear]
1943
+ # [<tt>collection.clear</tt>]
1819
1944
  # Removes every object from the collection. This does not destroy the objects.
1820
- # [collection.empty?]
1945
+ # [<tt>collection.empty?</tt>]
1821
1946
  # Returns +true+ if there are no associated objects.
1822
- # [collection.size]
1947
+ # [<tt>collection.size</tt>]
1823
1948
  # Returns the number of associated objects.
1824
- # [collection.find(id)]
1949
+ # [<tt>collection.find(id)</tt>]
1825
1950
  # Finds an associated object responding to the +id+ and that
1826
1951
  # meets the condition that it has to be associated with this object.
1827
1952
  # Uses the same rules as ActiveRecord::FinderMethods#find.
1828
- # [collection.exists?(...)]
1953
+ # [<tt>collection.exists?(...)</tt>]
1829
1954
  # Checks whether an associated object with the given conditions exists.
1830
1955
  # Uses the same rules as ActiveRecord::FinderMethods#exists?.
1831
- # [collection.build(attributes = {})]
1956
+ # [<tt>collection.build(attributes = {})</tt>]
1832
1957
  # Returns a new object of the collection type that has been instantiated
1833
1958
  # with +attributes+ and linked to this object through the join table, but has not yet been saved.
1834
- # [collection.create(attributes = {})]
1959
+ # [<tt>collection.create(attributes = {})</tt>]
1835
1960
  # Returns a new object of the collection type that has been instantiated
1836
1961
  # with +attributes+, linked to this object through the join table, and that has already been
1837
1962
  # saved (if it passed the validation).
1838
- # [collection.reload]
1963
+ # [<tt>collection.reload</tt>]
1839
1964
  # Returns a Relation of all of the associated objects, forcing a database read.
1840
1965
  # An empty Relation is returned if none are found.
1841
1966
  #
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>
1967
+ # ==== Example
1968
+ #
1969
+ # class Developer < ActiveRecord::Base
1970
+ # has_and_belongs_to_many :projects
1971
+ # end
1972
+ #
1973
+ # Declaring <tt>has_and_belongs_to_many :projects</tt> adds the following methods (and more):
1974
+ #
1975
+ # developer = Developer.find(11)
1976
+ # project = Project.find(9)
1977
+ #
1978
+ # developer.projects
1979
+ # developer.projects << project
1980
+ # developer.projects.delete(project)
1981
+ # developer.projects.destroy(project)
1982
+ # developer.projects = [project]
1983
+ # developer.project_ids
1984
+ # developer.project_ids = [9]
1985
+ # developer.projects.clear
1986
+ # developer.projects.empty?
1987
+ # developer.projects.size
1988
+ # developer.projects.find(9)
1989
+ # developer.projects.exists?(9)
1990
+ # developer.projects.build # similar to Project.new(developer_id: 11)
1991
+ # developer.projects.create # similar to Project.create(developer_id: 11)
1992
+ # developer.projects.reload
1993
+ #
1860
1994
  # The declaration may include an +options+ hash to specialize the behavior of the association.
1861
1995
  #
1862
- # === Scopes
1996
+ # ==== Scopes
1863
1997
  #
1864
1998
  # You can pass a second argument +scope+ as a callable (i.e. proc or
1865
1999
  # lambda) to retrieve a specific set of records or customize the generated
@@ -1871,11 +2005,11 @@ module ActiveRecord
1871
2005
  # where("default_category = ?", post.default_category)
1872
2006
  # }
1873
2007
  #
1874
- # === Extensions
2008
+ # ==== Extensions
1875
2009
  #
1876
2010
  # The +extension+ argument allows you to pass a block into a
1877
2011
  # 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
2012
+ # finders, creators, and other factory-type methods to be used as part of
1879
2013
  # the association.
1880
2014
  #
1881
2015
  # Extension examples:
@@ -1886,33 +2020,33 @@ module ActiveRecord
1886
2020
  # end
1887
2021
  # end
1888
2022
  #
1889
- # === Options
2023
+ # ==== Options
1890
2024
  #
1891
- # [:class_name]
2025
+ # [+:class_name+]
1892
2026
  # Specify the class name of the association. Use it only if that name can't be inferred
1893
2027
  # from the association name. So <tt>has_and_belongs_to_many :projects</tt> will by default be linked to the
1894
2028
  # Project class, but if the real class name is SuperProject, you'll have to specify it with this option.
1895
- # [:join_table]
2029
+ # [+:join_table+]
1896
2030
  # Specify the name of the join table if the default based on lexical order isn't what you want.
1897
2031
  # <b>WARNING:</b> If you're overwriting the table name of either class, the +table_name+ method
1898
2032
  # MUST be declared underneath any #has_and_belongs_to_many declaration in order to work.
1899
- # [:foreign_key]
2033
+ # [+:foreign_key+]
1900
2034
  # Specify the foreign key used for the association. By default this is guessed to be the name
1901
2035
  # of this class in lower-case and "_id" suffixed. So a Person class that makes
1902
2036
  # a #has_and_belongs_to_many association to Project will use "person_id" as the
1903
2037
  # default <tt>:foreign_key</tt>.
1904
2038
  #
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]
2039
+ # Setting the <tt>:foreign_key</tt> option prevents automatic detection of the association's
2040
+ # inverse, so it is generally a good idea to set the <tt>:inverse_of</tt> option as well.
2041
+ # [+:association_foreign_key+]
1908
2042
  # Specify the foreign key used for the association on the receiving side of the association.
1909
2043
  # By default this is guessed to be the name of the associated class in lower-case and "_id" suffixed.
1910
2044
  # So if a Person class makes a #has_and_belongs_to_many association to Project,
1911
2045
  # the association will use "project_id" as the default <tt>:association_foreign_key</tt>.
1912
- # [:validate]
2046
+ # [+:validate+]
1913
2047
  # When set to +true+, validates new objects added to association when saving the parent object. +true+ by default.
1914
2048
  # If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
1915
- # [:autosave]
2049
+ # [+:autosave+]
1916
2050
  # If true, always save the associated objects or destroy them if marked for destruction, when
1917
2051
  # saving the parent object.
1918
2052
  # If false, never save or destroy the associated objects.
@@ -1920,7 +2054,7 @@ module ActiveRecord
1920
2054
  #
1921
2055
  # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
1922
2056
  # <tt>:autosave</tt> to <tt>true</tt>.
1923
- # [:strict_loading]
2057
+ # [+:strict_loading+]
1924
2058
  # Enforces strict loading every time an associated record is loaded through this association.
1925
2059
  #
1926
2060
  # Option examples: