activerecord 7.0.4.3 → 7.1.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (242) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1657 -1274
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +18 -18
  5. data/lib/active_record/aggregations.rb +16 -13
  6. data/lib/active_record/association_relation.rb +1 -1
  7. data/lib/active_record/associations/association.rb +20 -4
  8. data/lib/active_record/associations/association_scope.rb +16 -9
  9. data/lib/active_record/associations/belongs_to_association.rb +14 -6
  10. data/lib/active_record/associations/builder/association.rb +3 -3
  11. data/lib/active_record/associations/builder/belongs_to.rb +21 -8
  12. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -5
  13. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  14. data/lib/active_record/associations/collection_association.rb +16 -10
  15. data/lib/active_record/associations/collection_proxy.rb +20 -10
  16. data/lib/active_record/associations/foreign_association.rb +10 -3
  17. data/lib/active_record/associations/has_many_association.rb +20 -13
  18. data/lib/active_record/associations/has_many_through_association.rb +10 -6
  19. data/lib/active_record/associations/has_one_association.rb +10 -3
  20. data/lib/active_record/associations/join_dependency.rb +10 -8
  21. data/lib/active_record/associations/preloader/association.rb +31 -7
  22. data/lib/active_record/associations/preloader/through_association.rb +1 -1
  23. data/lib/active_record/associations/preloader.rb +13 -10
  24. data/lib/active_record/associations/singular_association.rb +1 -1
  25. data/lib/active_record/associations/through_association.rb +22 -11
  26. data/lib/active_record/associations.rb +327 -222
  27. data/lib/active_record/attribute_assignment.rb +0 -2
  28. data/lib/active_record/attribute_methods/before_type_cast.rb +17 -0
  29. data/lib/active_record/attribute_methods/dirty.rb +52 -34
  30. data/lib/active_record/attribute_methods/primary_key.rb +76 -24
  31. data/lib/active_record/attribute_methods/query.rb +28 -16
  32. data/lib/active_record/attribute_methods/read.rb +18 -5
  33. data/lib/active_record/attribute_methods/serialization.rb +150 -31
  34. data/lib/active_record/attribute_methods/time_zone_conversion.rb +0 -4
  35. data/lib/active_record/attribute_methods/write.rb +3 -3
  36. data/lib/active_record/attribute_methods.rb +108 -26
  37. data/lib/active_record/attributes.rb +3 -3
  38. data/lib/active_record/autosave_association.rb +55 -9
  39. data/lib/active_record/base.rb +7 -2
  40. data/lib/active_record/callbacks.rb +16 -32
  41. data/lib/active_record/coders/column_serializer.rb +61 -0
  42. data/lib/active_record/coders/json.rb +1 -1
  43. data/lib/active_record/coders/yaml_column.rb +70 -42
  44. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +163 -88
  45. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +2 -0
  46. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +3 -1
  47. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +74 -51
  48. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
  49. data/lib/active_record/connection_adapters/abstract/database_statements.rb +129 -31
  50. data/lib/active_record/connection_adapters/abstract/query_cache.rb +62 -23
  51. data/lib/active_record/connection_adapters/abstract/quoting.rb +41 -6
  52. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
  53. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +18 -4
  54. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +155 -25
  55. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +290 -124
  56. data/lib/active_record/connection_adapters/abstract/transaction.rb +287 -58
  57. data/lib/active_record/connection_adapters/abstract_adapter.rb +509 -102
  58. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +217 -112
  59. data/lib/active_record/connection_adapters/column.rb +9 -0
  60. data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
  61. data/lib/active_record/connection_adapters/mysql/database_statements.rb +23 -144
  62. data/lib/active_record/connection_adapters/mysql/quoting.rb +29 -14
  63. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
  64. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
  65. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
  66. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +18 -13
  67. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +151 -0
  68. data/lib/active_record/connection_adapters/mysql2_adapter.rb +98 -53
  69. data/lib/active_record/connection_adapters/pool_config.rb +14 -5
  70. data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
  71. data/lib/active_record/connection_adapters/postgresql/column.rb +16 -3
  72. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +75 -45
  73. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  74. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
  75. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +11 -2
  76. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +2 -2
  77. data/lib/active_record/connection_adapters/postgresql/quoting.rb +15 -8
  78. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +3 -9
  79. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -6
  80. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +131 -2
  81. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +53 -0
  82. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +362 -60
  83. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
  84. data/lib/active_record/connection_adapters/postgresql_adapter.rb +354 -193
  85. data/lib/active_record/connection_adapters/schema_cache.rb +287 -59
  86. data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
  87. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +52 -39
  88. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +9 -5
  89. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +7 -0
  90. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +28 -9
  91. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +211 -83
  92. data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
  93. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
  94. data/lib/active_record/connection_adapters/trilogy_adapter.rb +262 -0
  95. data/lib/active_record/connection_adapters.rb +3 -1
  96. data/lib/active_record/connection_handling.rb +72 -95
  97. data/lib/active_record/core.rb +175 -153
  98. data/lib/active_record/counter_cache.rb +46 -25
  99. data/lib/active_record/database_configurations/database_config.rb +9 -3
  100. data/lib/active_record/database_configurations/hash_config.rb +22 -12
  101. data/lib/active_record/database_configurations/url_config.rb +17 -11
  102. data/lib/active_record/database_configurations.rb +86 -33
  103. data/lib/active_record/delegated_type.rb +9 -4
  104. data/lib/active_record/deprecator.rb +7 -0
  105. data/lib/active_record/destroy_association_async_job.rb +2 -0
  106. data/lib/active_record/disable_joins_association_relation.rb +1 -1
  107. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  108. data/lib/active_record/encryption/cipher/aes256_gcm.rb +4 -1
  109. data/lib/active_record/encryption/config.rb +25 -1
  110. data/lib/active_record/encryption/configurable.rb +12 -19
  111. data/lib/active_record/encryption/context.rb +10 -3
  112. data/lib/active_record/encryption/contexts.rb +5 -1
  113. data/lib/active_record/encryption/derived_secret_key_provider.rb +8 -2
  114. data/lib/active_record/encryption/encryptable_record.rb +42 -18
  115. data/lib/active_record/encryption/encrypted_attribute_type.rb +21 -6
  116. data/lib/active_record/encryption/extended_deterministic_queries.rb +66 -69
  117. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +3 -3
  118. data/lib/active_record/encryption/key_generator.rb +12 -1
  119. data/lib/active_record/encryption/message_serializer.rb +2 -0
  120. data/lib/active_record/encryption/properties.rb +3 -3
  121. data/lib/active_record/encryption/scheme.rb +19 -22
  122. data/lib/active_record/encryption.rb +1 -0
  123. data/lib/active_record/enum.rb +112 -28
  124. data/lib/active_record/errors.rb +112 -18
  125. data/lib/active_record/explain.rb +23 -3
  126. data/lib/active_record/explain_subscriber.rb +1 -1
  127. data/lib/active_record/fixture_set/model_metadata.rb +14 -4
  128. data/lib/active_record/fixture_set/render_context.rb +2 -0
  129. data/lib/active_record/fixture_set/table_row.rb +29 -8
  130. data/lib/active_record/fixtures.rb +135 -71
  131. data/lib/active_record/future_result.rb +31 -5
  132. data/lib/active_record/gem_version.rb +4 -4
  133. data/lib/active_record/inheritance.rb +30 -16
  134. data/lib/active_record/insert_all.rb +57 -10
  135. data/lib/active_record/integration.rb +8 -8
  136. data/lib/active_record/internal_metadata.rb +120 -30
  137. data/lib/active_record/locking/optimistic.rb +32 -18
  138. data/lib/active_record/locking/pessimistic.rb +5 -2
  139. data/lib/active_record/log_subscriber.rb +29 -12
  140. data/lib/active_record/marshalling.rb +56 -0
  141. data/lib/active_record/message_pack.rb +124 -0
  142. data/lib/active_record/middleware/database_selector/resolver.rb +4 -0
  143. data/lib/active_record/middleware/database_selector.rb +9 -11
  144. data/lib/active_record/middleware/shard_selector.rb +3 -1
  145. data/lib/active_record/migration/command_recorder.rb +105 -7
  146. data/lib/active_record/migration/compatibility.rb +157 -58
  147. data/lib/active_record/migration/default_strategy.rb +23 -0
  148. data/lib/active_record/migration/execution_strategy.rb +19 -0
  149. data/lib/active_record/migration/pending_migration_connection.rb +21 -0
  150. data/lib/active_record/migration.rb +271 -114
  151. data/lib/active_record/model_schema.rb +64 -44
  152. data/lib/active_record/nested_attributes.rb +24 -6
  153. data/lib/active_record/normalization.rb +167 -0
  154. data/lib/active_record/persistence.rb +195 -42
  155. data/lib/active_record/promise.rb +84 -0
  156. data/lib/active_record/query_cache.rb +3 -21
  157. data/lib/active_record/query_logs.rb +77 -52
  158. data/lib/active_record/query_logs_formatter.rb +41 -0
  159. data/lib/active_record/querying.rb +15 -2
  160. data/lib/active_record/railtie.rb +109 -47
  161. data/lib/active_record/railties/controller_runtime.rb +14 -9
  162. data/lib/active_record/railties/databases.rake +142 -148
  163. data/lib/active_record/railties/job_runtime.rb +23 -0
  164. data/lib/active_record/readonly_attributes.rb +32 -5
  165. data/lib/active_record/reflection.rb +182 -44
  166. data/lib/active_record/relation/batches/batch_enumerator.rb +5 -3
  167. data/lib/active_record/relation/batches.rb +190 -61
  168. data/lib/active_record/relation/calculations.rb +232 -81
  169. data/lib/active_record/relation/delegation.rb +23 -9
  170. data/lib/active_record/relation/finder_methods.rb +77 -16
  171. data/lib/active_record/relation/merger.rb +2 -0
  172. data/lib/active_record/relation/predicate_builder/association_query_value.rb +31 -3
  173. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -6
  174. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  175. data/lib/active_record/relation/predicate_builder.rb +26 -14
  176. data/lib/active_record/relation/query_attribute.rb +25 -1
  177. data/lib/active_record/relation/query_methods.rb +387 -71
  178. data/lib/active_record/relation/spawn_methods.rb +18 -1
  179. data/lib/active_record/relation.rb +91 -35
  180. data/lib/active_record/result.rb +25 -9
  181. data/lib/active_record/runtime_registry.rb +24 -1
  182. data/lib/active_record/sanitization.rb +51 -11
  183. data/lib/active_record/schema.rb +2 -3
  184. data/lib/active_record/schema_dumper.rb +50 -7
  185. data/lib/active_record/schema_migration.rb +68 -33
  186. data/lib/active_record/scoping/default.rb +15 -5
  187. data/lib/active_record/scoping/named.rb +2 -2
  188. data/lib/active_record/scoping.rb +2 -1
  189. data/lib/active_record/secure_password.rb +60 -0
  190. data/lib/active_record/secure_token.rb +21 -3
  191. data/lib/active_record/signed_id.rb +7 -5
  192. data/lib/active_record/store.rb +9 -9
  193. data/lib/active_record/suppressor.rb +3 -1
  194. data/lib/active_record/table_metadata.rb +16 -3
  195. data/lib/active_record/tasks/database_tasks.rb +127 -105
  196. data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
  197. data/lib/active_record/tasks/postgresql_database_tasks.rb +16 -13
  198. data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
  199. data/lib/active_record/test_fixtures.rb +113 -96
  200. data/lib/active_record/timestamp.rb +27 -15
  201. data/lib/active_record/token_for.rb +113 -0
  202. data/lib/active_record/touch_later.rb +11 -6
  203. data/lib/active_record/transactions.rb +39 -13
  204. data/lib/active_record/type/adapter_specific_registry.rb +1 -8
  205. data/lib/active_record/type/internal/timezone.rb +7 -2
  206. data/lib/active_record/type/serialized.rb +8 -4
  207. data/lib/active_record/type/time.rb +4 -0
  208. data/lib/active_record/validations/absence.rb +1 -1
  209. data/lib/active_record/validations/numericality.rb +5 -4
  210. data/lib/active_record/validations/presence.rb +5 -28
  211. data/lib/active_record/validations/uniqueness.rb +47 -2
  212. data/lib/active_record/validations.rb +8 -4
  213. data/lib/active_record/version.rb +1 -1
  214. data/lib/active_record.rb +121 -16
  215. data/lib/arel/errors.rb +10 -0
  216. data/lib/arel/factory_methods.rb +4 -0
  217. data/lib/arel/filter_predications.rb +1 -1
  218. data/lib/arel/nodes/and.rb +4 -0
  219. data/lib/arel/nodes/binary.rb +6 -1
  220. data/lib/arel/nodes/bound_sql_literal.rb +61 -0
  221. data/lib/arel/nodes/cte.rb +36 -0
  222. data/lib/arel/nodes/filter.rb +1 -1
  223. data/lib/arel/nodes/fragments.rb +35 -0
  224. data/lib/arel/nodes/homogeneous_in.rb +1 -9
  225. data/lib/arel/nodes/leading_join.rb +8 -0
  226. data/lib/arel/nodes/node.rb +111 -2
  227. data/lib/arel/nodes/sql_literal.rb +6 -0
  228. data/lib/arel/nodes/table_alias.rb +4 -0
  229. data/lib/arel/nodes.rb +4 -0
  230. data/lib/arel/predications.rb +2 -0
  231. data/lib/arel/table.rb +9 -5
  232. data/lib/arel/visitors/mysql.rb +8 -1
  233. data/lib/arel/visitors/to_sql.rb +81 -17
  234. data/lib/arel/visitors/visitor.rb +2 -2
  235. data/lib/arel.rb +16 -2
  236. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  237. data/lib/rails/generators/active_record/migration.rb +3 -1
  238. data/lib/rails/generators/active_record/model/USAGE +113 -0
  239. data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
  240. metadata +48 -12
  241. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
  242. data/lib/active_record/null_relation.rb +0 -63
@@ -184,6 +184,22 @@ module ActiveRecord
184
184
  end
185
185
  end
186
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
+
187
203
  class AmbiguousSourceReflectionForThroughAssociation < ActiveRecordError # :nodoc:
188
204
  def initialize(klass, macro, association_name, options, possible_sources)
189
205
  example_options = options.dup
@@ -319,8 +335,8 @@ module ActiveRecord
319
335
 
320
336
  private
321
337
  def init_internals
322
- @association_cache = {}
323
338
  super
339
+ @association_cache = {}
324
340
  end
325
341
 
326
342
  # Returns the specified association instance if it exists, +nil+ otherwise.
@@ -333,6 +349,8 @@ module ActiveRecord
333
349
  @association_cache[name] = association
334
350
  end
335
351
 
352
+ # = Active Record \Associations
353
+ #
336
354
  # \Associations are a set of macro-like class methods for tying objects together through
337
355
  # foreign keys. They express relationships like "Project has one Project Manager"
338
356
  # or "Project belongs to a Portfolio". Each macro adds a number of methods to the
@@ -349,23 +367,42 @@ module ActiveRecord
349
367
  #
350
368
  # The project class now has the following methods (and more) to ease the traversal and
351
369
  # manipulation of its relationships:
352
- # * <tt>Project#portfolio</tt>, <tt>Project#portfolio=(portfolio)</tt>, <tt>Project#reload_portfolio</tt>
353
- # * <tt>Project#project_manager</tt>, <tt>Project#project_manager=(project_manager)</tt>, <tt>Project#reload_project_manager</tt>
354
- # * <tt>Project#milestones.empty?</tt>, <tt>Project#milestones.size</tt>, <tt>Project#milestones</tt>, <tt>Project#milestones<<(milestone)</tt>,
355
- # <tt>Project#milestones.delete(milestone)</tt>, <tt>Project#milestones.destroy(milestone)</tt>, <tt>Project#milestones.find(milestone_id)</tt>,
356
- # <tt>Project#milestones.build</tt>, <tt>Project#milestones.create</tt>
357
- # * <tt>Project#categories.empty?</tt>, <tt>Project#categories.size</tt>, <tt>Project#categories</tt>, <tt>Project#categories<<(category1)</tt>,
358
- # <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)
359
396
  #
360
397
  # === A word of warning
361
398
  #
362
399
  # Don't create associations that have the same name as {instance methods}[rdoc-ref:ActiveRecord::Core] of
363
- # <tt>ActiveRecord::Base</tt>. Since the association adds a method with that name to
364
- # 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.
365
- # 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.
366
403
  #
367
404
  # == Auto-generated methods
368
- # See also Instance Public methods below for more details.
405
+ # See also "Instance Public methods" below ( from #belongs_to ) for more details.
369
406
  #
370
407
  # === Singular associations (one-to-one)
371
408
  # | | belongs_to |
@@ -586,8 +623,11 @@ module ActiveRecord
586
623
  # has_many :birthday_events, ->(user) { where(starts_on: user.birthday) }, class_name: 'Event'
587
624
  # end
588
625
  #
589
- # Note: Joining, eager loading, and preloading of these associations is not possible.
590
- # 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).
591
631
  #
592
632
  # == Association callbacks
593
633
  #
@@ -608,6 +648,7 @@ module ActiveRecord
608
648
  # def log_after_remove(record)
609
649
  # # ...
610
650
  # end
651
+ # end
611
652
  #
612
653
  # It's possible to stack callbacks by passing them as an array. Example:
613
654
  #
@@ -1009,7 +1050,7 @@ module ActiveRecord
1009
1050
  # query per addressable type.
1010
1051
  # For example, if all the addressables are either of class Person or Company, then a total
1011
1052
  # of 3 queries will be executed. The list of addressable types to load is determined on
1012
- # the back of the addresses loaded. This is not supported if Active Record has to fallback
1053
+ # the back of the addresses loaded. This is not supported if Active Record has to fall back
1013
1054
  # to the previous implementation of eager loading and will raise ActiveRecord::EagerLoadPolymorphicError.
1014
1055
  # The reason is that the parent model's type is a column value so its corresponding table
1015
1056
  # name cannot be put in the +FROM+/+JOIN+ clauses of that query.
@@ -1022,45 +1063,45 @@ module ActiveRecord
1022
1063
  # Indexes are appended for any more successive uses of the table name.
1023
1064
  #
1024
1065
  # Post.joins(:comments)
1025
- # # => SELECT ... FROM posts INNER JOIN comments ON ...
1066
+ # # SELECT ... FROM posts INNER JOIN comments ON ...
1026
1067
  # Post.joins(:special_comments) # STI
1027
- # # => SELECT ... FROM posts INNER JOIN comments ON ... AND comments.type = 'SpecialComment'
1068
+ # # SELECT ... FROM posts INNER JOIN comments ON ... AND comments.type = 'SpecialComment'
1028
1069
  # Post.joins(:comments, :special_comments) # special_comments is the reflection name, posts is the parent table name
1029
- # # => 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
1030
1071
  #
1031
1072
  # Acts as tree example:
1032
1073
  #
1033
1074
  # TreeMixin.joins(:children)
1034
- # # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
1075
+ # # SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
1035
1076
  # TreeMixin.joins(children: :parent)
1036
- # # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
1037
- # INNER JOIN parents_mixins ...
1077
+ # # SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
1078
+ # # INNER JOIN parents_mixins ...
1038
1079
  # TreeMixin.joins(children: {parent: :children})
1039
- # # => SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
1040
- # INNER JOIN parents_mixins ...
1041
- # 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
1042
1083
  #
1043
1084
  # Has and Belongs to Many join tables use the same idea, but add a <tt>_join</tt> suffix:
1044
1085
  #
1045
1086
  # Post.joins(:categories)
1046
- # # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
1087
+ # # SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
1047
1088
  # Post.joins(categories: :posts)
1048
- # # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
1049
- # 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
1050
1091
  # Post.joins(categories: {posts: :categories})
1051
- # # => SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
1052
- # INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
1053
- # 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
1054
1095
  #
1055
1096
  # If you wish to specify your own custom joins using ActiveRecord::QueryMethods#joins method, those table
1056
1097
  # names will take precedence over the eager associations:
1057
1098
  #
1058
1099
  # Post.joins(:comments).joins("inner join comments ...")
1059
- # # => SELECT ... FROM posts INNER JOIN comments_posts ON ... INNER JOIN comments ...
1100
+ # # SELECT ... FROM posts INNER JOIN comments_posts ON ... INNER JOIN comments ...
1060
1101
  # Post.joins(:comments, :special_comments).joins("inner join comments ...")
1061
- # # => SELECT ... FROM posts INNER JOIN comments comments_posts ON ...
1062
- # INNER JOIN comments special_comments_posts ...
1063
- # INNER JOIN comments ...
1102
+ # # SELECT ... FROM posts INNER JOIN comments comments_posts ON ...
1103
+ # # INNER JOIN comments special_comments_posts ...
1104
+ # # INNER JOIN comments ...
1064
1105
  #
1065
1106
  # Table aliases are automatically truncated according to the maximum length of table identifiers
1066
1107
  # according to the specific database.
@@ -1141,7 +1182,8 @@ module ActiveRecord
1141
1182
  # belongs_to :dungeon, inverse_of: :evil_wizard
1142
1183
  # end
1143
1184
  #
1144
- # 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].
1145
1187
  #
1146
1188
  # == Deleting from associations
1147
1189
  #
@@ -1163,7 +1205,7 @@ module ActiveRecord
1163
1205
  # specific association types. When no option is given, the behavior is to do nothing
1164
1206
  # with the associated records when destroying a record.
1165
1207
  #
1166
- # Note that <tt>:dependent</tt> is implemented using Rails' callback
1208
+ # Note that <tt>:dependent</tt> is implemented using \Rails' callback
1167
1209
  # system, which works by processing callbacks in order. Therefore, other
1168
1210
  # callbacks declared either before or after the <tt>:dependent</tt> option
1169
1211
  # can affect what it does.
@@ -1234,15 +1276,15 @@ module ActiveRecord
1234
1276
  # +collection+ is a placeholder for the symbol passed as the +name+ argument, so
1235
1277
  # <tt>has_many :clients</tt> would add among others <tt>clients.empty?</tt>.
1236
1278
  #
1237
- # [collection]
1279
+ # [<tt>collection</tt>]
1238
1280
  # Returns a Relation of all the associated objects.
1239
1281
  # An empty Relation is returned if none are found.
1240
- # [collection<<(object, ...)]
1282
+ # [<tt>collection<<(object, ...)</tt>]
1241
1283
  # Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
1242
1284
  # Note that this operation instantly fires update SQL without waiting for the save or update call on the
1243
1285
  # parent object, unless the parent object is a new record.
1244
1286
  # This will also run validations and callbacks of associated object(s).
1245
- # [collection.delete(object, ...)]
1287
+ # [<tt>collection.delete(object, ...)</tt>]
1246
1288
  # Removes one or more objects from the collection by setting their foreign keys to +NULL+.
1247
1289
  # Objects will be in addition destroyed if they're associated with <tt>dependent: :destroy</tt>,
1248
1290
  # and deleted if they're associated with <tt>dependent: :delete_all</tt>.
@@ -1250,75 +1292,84 @@ module ActiveRecord
1250
1292
  # If the <tt>:through</tt> option is used, then the join records are deleted (rather than
1251
1293
  # nullified) by default, but you can specify <tt>dependent: :destroy</tt> or
1252
1294
  # <tt>dependent: :nullify</tt> to override this.
1253
- # [collection.destroy(object, ...)]
1295
+ # [<tt>collection.destroy(object, ...)</tt>]
1254
1296
  # Removes one or more objects from the collection by running <tt>destroy</tt> on
1255
1297
  # each record, regardless of any dependent option, ensuring callbacks are run.
1256
1298
  #
1257
1299
  # If the <tt>:through</tt> option is used, then the join records are destroyed
1258
1300
  # instead, not the objects themselves.
1259
- # [collection=objects]
1301
+ # [<tt>collection=objects</tt>]
1260
1302
  # Replaces the collections content by deleting and adding objects as appropriate. If the <tt>:through</tt>
1261
1303
  # option is true callbacks in the join models are triggered except destroy callbacks, since deletion is
1262
1304
  # direct by default. You can specify <tt>dependent: :destroy</tt> or
1263
1305
  # <tt>dependent: :nullify</tt> to override this.
1264
- # [collection_singular_ids]
1306
+ # [<tt>collection_singular_ids</tt>]
1265
1307
  # Returns an array of the associated objects' ids
1266
- # [collection_singular_ids=ids]
1308
+ # [<tt>collection_singular_ids=ids</tt>]
1267
1309
  # Replace the collection with the objects identified by the primary keys in +ids+. This
1268
1310
  # method loads the models and calls <tt>collection=</tt>. See above.
1269
- # [collection.clear]
1311
+ # [<tt>collection.clear</tt>]
1270
1312
  # Removes every object from the collection. This destroys the associated objects if they
1271
1313
  # are associated with <tt>dependent: :destroy</tt>, deletes them directly from the
1272
1314
  # database if <tt>dependent: :delete_all</tt>, otherwise sets their foreign keys to +NULL+.
1273
1315
  # If the <tt>:through</tt> option is true no destroy callbacks are invoked on the join models.
1274
1316
  # Join models are directly deleted.
1275
- # [collection.empty?]
1317
+ # [<tt>collection.empty?</tt>]
1276
1318
  # Returns +true+ if there are no associated objects.
1277
- # [collection.size]
1319
+ # [<tt>collection.size</tt>]
1278
1320
  # Returns the number of associated objects.
1279
- # [collection.find(...)]
1321
+ # [<tt>collection.find(...)</tt>]
1280
1322
  # Finds an associated object according to the same rules as ActiveRecord::FinderMethods#find.
1281
- # [collection.exists?(...)]
1323
+ # [<tt>collection.exists?(...)</tt>]
1282
1324
  # Checks whether an associated object with the given conditions exists.
1283
1325
  # Uses the same rules as ActiveRecord::FinderMethods#exists?.
1284
- # [collection.build(attributes = {}, ...)]
1326
+ # [<tt>collection.build(attributes = {}, ...)</tt>]
1285
1327
  # Returns one or more new objects of the collection type that have been instantiated
1286
1328
  # with +attributes+ and linked to this object through a foreign key, but have not yet
1287
1329
  # been saved.
1288
- # [collection.create(attributes = {})]
1330
+ # [<tt>collection.create(attributes = {})</tt>]
1289
1331
  # Returns a new object of the collection type that has been instantiated
1290
1332
  # with +attributes+, linked to this object through a foreign key, and that has already
1291
1333
  # been saved (if it passed the validation). *Note*: This only works if the base model
1292
1334
  # already exists in the DB, not if it is a new (unsaved) record!
1293
- # [collection.create!(attributes = {})]
1335
+ # [<tt>collection.create!(attributes = {})</tt>]
1294
1336
  # Does the same as <tt>collection.create</tt>, but raises ActiveRecord::RecordInvalid
1295
1337
  # if the record is invalid.
1296
- # [collection.reload]
1338
+ # [<tt>collection.reload</tt>]
1297
1339
  # Returns a Relation of all of the associated objects, forcing a database read.
1298
1340
  # An empty Relation is returned if none are found.
1299
1341
  #
1300
- # === Example
1301
- #
1302
- # A <tt>Firm</tt> class declares <tt>has_many :clients</tt>, which will add:
1303
- # * <tt>Firm#clients</tt> (similar to <tt>Client.where(firm_id: id)</tt>)
1304
- # * <tt>Firm#clients<<</tt>
1305
- # * <tt>Firm#clients.delete</tt>
1306
- # * <tt>Firm#clients.destroy</tt>
1307
- # * <tt>Firm#clients=</tt>
1308
- # * <tt>Firm#client_ids</tt>
1309
- # * <tt>Firm#client_ids=</tt>
1310
- # * <tt>Firm#clients.clear</tt>
1311
- # * <tt>Firm#clients.empty?</tt> (similar to <tt>firm.clients.size == 0</tt>)
1312
- # * <tt>Firm#clients.size</tt> (similar to <tt>Client.count "firm_id = #{id}"</tt>)
1313
- # * <tt>Firm#clients.find</tt> (similar to <tt>Client.where(firm_id: id).find(id)</tt>)
1314
- # * <tt>Firm#clients.exists?(name: 'ACME')</tt> (similar to <tt>Client.exists?(name: 'ACME', firm_id: firm.id)</tt>)
1315
- # * <tt>Firm#clients.build</tt> (similar to <tt>Client.new(firm_id: id)</tt>)
1316
- # * <tt>Firm#clients.create</tt> (similar to <tt>c = Client.new(firm_id: id); c.save; c</tt>)
1317
- # * <tt>Firm#clients.create!</tt> (similar to <tt>c = Client.new(firm_id: id); c.save!</tt>)
1318
- # * <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
+ #
1319
1370
  # The declaration can also include an +options+ hash to specialize the behavior of the association.
1320
1371
  #
1321
- # === Scopes
1372
+ # ==== Scopes
1322
1373
  #
1323
1374
  # You can pass a second argument +scope+ as a callable (i.e. proc or
1324
1375
  # lambda) to retrieve a specific set of records or customize the generated
@@ -1329,7 +1380,7 @@ module ActiveRecord
1329
1380
  # has_many :employees, -> { joins(:address) }
1330
1381
  # has_many :posts, ->(blog) { where("max_post_length > ?", blog.max_post_length) }
1331
1382
  #
1332
- # === Extensions
1383
+ # ==== Extensions
1333
1384
  #
1334
1385
  # The +extension+ argument allows you to pass a block into a has_many
1335
1386
  # association. This is useful for adding new finders, creators, and other
@@ -1343,31 +1394,31 @@ module ActiveRecord
1343
1394
  # end
1344
1395
  # end
1345
1396
  #
1346
- # === Options
1347
- # [:class_name]
1397
+ # ==== Options
1398
+ # [+:class_name+]
1348
1399
  # Specify the class name of the association. Use it only if that name can't be inferred
1349
1400
  # from the association name. So <tt>has_many :products</tt> will by default be linked
1350
1401
  # to the +Product+ class, but if the real class name is +SpecialProduct+, you'll have to
1351
1402
  # specify it with this option.
1352
- # [:foreign_key]
1403
+ # [+:foreign_key+]
1353
1404
  # Specify the foreign key used for the association. By default this is guessed to be the name
1354
1405
  # of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_many
1355
1406
  # association will use "person_id" as the default <tt>:foreign_key</tt>.
1356
1407
  #
1357
- # If you are going to modify the association (rather than just read from it), then it is
1358
- # a good idea to set the <tt>:inverse_of</tt> option.
1359
- # [: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+]
1360
1411
  # Specify the column used to store the associated object's type, if this is a polymorphic
1361
1412
  # association. By default this is guessed to be the name of the polymorphic association
1362
1413
  # specified on "as" option with a "_type" suffix. So a class that defines a
1363
1414
  # <tt>has_many :tags, as: :taggable</tt> association will use "taggable_type" as the
1364
1415
  # default <tt>:foreign_type</tt>.
1365
- # [:primary_key]
1416
+ # [+:primary_key+]
1366
1417
  # Specify the name of the column to use as the primary key for the association. By default this is +id+.
1367
- # [:dependent]
1418
+ # [+:dependent+]
1368
1419
  # Controls what happens to the associated objects when
1369
1420
  # their owner is destroyed. Note that these are implemented as
1370
- # callbacks, and Rails executes callbacks in order. Therefore, other
1421
+ # callbacks, and \Rails executes callbacks in order. Therefore, other
1371
1422
  # similar callbacks may affect the <tt>:dependent</tt> behavior, and the
1372
1423
  # <tt>:dependent</tt> behavior may affect other callbacks.
1373
1424
  #
@@ -1379,7 +1430,7 @@ module ActiveRecord
1379
1430
  # * <tt>:delete_all</tt> causes all the associated objects to be deleted directly from the database (so callbacks will not be executed).
1380
1431
  # * <tt>:nullify</tt> causes the foreign keys to be set to +NULL+. Polymorphic type will also be nullified
1381
1432
  # on polymorphic associations. Callbacks are not executed.
1382
- # * <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.
1383
1434
  # * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there are any associated objects.
1384
1435
  #
1385
1436
  # If using with the <tt>:through</tt> option, the association on the join model must be
@@ -1391,12 +1442,12 @@ module ActiveRecord
1391
1442
  # <tt>has_many :comments, -> { where published: true }, dependent: :destroy</tt> and <tt>destroy</tt> is
1392
1443
  # called on a post, only published comments are destroyed. This means that any unpublished comments in the
1393
1444
  # database would still contain a foreign key pointing to the now deleted post.
1394
- # [:counter_cache]
1445
+ # [+:counter_cache+]
1395
1446
  # This option can be used to configure a custom named <tt>:counter_cache.</tt> You only need this option,
1396
1447
  # when you customized the name of your <tt>:counter_cache</tt> on the #belongs_to association.
1397
- # [:as]
1448
+ # [+:as+]
1398
1449
  # Specifies a polymorphic interface (See #belongs_to).
1399
- # [:through]
1450
+ # [+:through+]
1400
1451
  # Specifies an association through which to perform the query. This can be any other type
1401
1452
  # of association, including other <tt>:through</tt> associations. Options for <tt>:class_name</tt>,
1402
1453
  # <tt>:primary_key</tt> and <tt>:foreign_key</tt> are ignored, as the association uses the
@@ -1411,24 +1462,24 @@ module ActiveRecord
1411
1462
  # a good idea to set the <tt>:inverse_of</tt> option on the source association on the
1412
1463
  # join model. This allows associated records to be built which will automatically create
1413
1464
  # the appropriate join model records when they are saved. (See the 'Association Join Models'
1414
- # section above.)
1415
- # [:disable_joins]
1465
+ # and 'Setting Inverses' sections above.)
1466
+ # [+:disable_joins+]
1416
1467
  # Specifies whether joins should be skipped for an association. If set to true, two or more queries
1417
1468
  # will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory
1418
1469
  # due to database limitations. This option is only applicable on <tt>has_many :through</tt> associations as
1419
1470
  # +has_many+ alone do not perform a join.
1420
- # [:source]
1471
+ # [+:source+]
1421
1472
  # Specifies the source association name used by #has_many <tt>:through</tt> queries.
1422
1473
  # Only use it if the name cannot be inferred from the association.
1423
1474
  # <tt>has_many :subscribers, through: :subscriptions</tt> will look for either <tt>:subscribers</tt> or
1424
1475
  # <tt>:subscriber</tt> on Subscription, unless a <tt>:source</tt> is given.
1425
- # [:source_type]
1476
+ # [+:source_type+]
1426
1477
  # Specifies type of the source association used by #has_many <tt>:through</tt> queries where the source
1427
1478
  # association is a polymorphic #belongs_to.
1428
- # [:validate]
1479
+ # [+:validate+]
1429
1480
  # When set to +true+, validates new objects added to association when saving the parent object. +true+ by default.
1430
1481
  # If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
1431
- # [:autosave]
1482
+ # [+:autosave+]
1432
1483
  # If true, always save the associated objects or destroy them if marked for destruction,
1433
1484
  # when saving the parent object. If false, never save or destroy the associated objects.
1434
1485
  # By default, only save associated objects that are new records. This option is implemented as a
@@ -1437,20 +1488,24 @@ module ActiveRecord
1437
1488
  #
1438
1489
  # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
1439
1490
  # <tt>:autosave</tt> to <tt>true</tt>.
1440
- # [:inverse_of]
1491
+ # [+:inverse_of+]
1441
1492
  # Specifies the name of the #belongs_to association on the associated object
1442
1493
  # that is the inverse of this #has_many association.
1443
1494
  # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1444
- # [:extend]
1495
+ # [+:extend+]
1445
1496
  # Specifies a module or array of modules that will be extended into the association object returned.
1446
1497
  # Useful for defining methods on associations, especially when they should be shared between multiple
1447
1498
  # association objects.
1448
- # [:strict_loading]
1499
+ # [+:strict_loading+]
1449
1500
  # When set to +true+, enforces strict loading every time the associated record is loaded through this
1450
1501
  # association.
1451
- # [:ensuring_owner_was]
1502
+ # [+:ensuring_owner_was+]
1452
1503
  # Specifies an instance method to be called on the owner. The method must return true in order for the
1453
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.
1454
1509
  #
1455
1510
  # Option examples:
1456
1511
  # has_many :comments, -> { order("posted_on") }
@@ -1463,6 +1518,7 @@ module ActiveRecord
1463
1518
  # has_many :subscribers, through: :subscriptions, source: :user
1464
1519
  # has_many :subscribers, through: :subscriptions, disable_joins: true
1465
1520
  # has_many :comments, strict_loading: true
1521
+ # has_many :comments, query_constraints: [:blog_id, :post_id]
1466
1522
  def has_many(name, scope = nil, **options, &extension)
1467
1523
  reflection = Builder::HasMany.build(self, name, scope, options, &extension)
1468
1524
  Reflection.add_reflection self, name, reflection
@@ -1478,37 +1534,48 @@ module ActiveRecord
1478
1534
  # +association+ is a placeholder for the symbol passed as the +name+ argument, so
1479
1535
  # <tt>has_one :manager</tt> would add among others <tt>manager.nil?</tt>.
1480
1536
  #
1481
- # [association]
1537
+ # [<tt>association</tt>]
1482
1538
  # Returns the associated object. +nil+ is returned if none is found.
1483
- # [association=(associate)]
1539
+ # [<tt>association=(associate)</tt>]
1484
1540
  # Assigns the associate object, extracts the primary key, sets it as the foreign key,
1485
1541
  # and saves the associate object. To avoid database inconsistencies, permanently deletes an existing
1486
1542
  # associated object when assigning a new one, even if the new one isn't saved to database.
1487
- # [build_association(attributes = {})]
1543
+ # [<tt>build_association(attributes = {})</tt>]
1488
1544
  # Returns a new object of the associated type that has been instantiated
1489
1545
  # with +attributes+ and linked to this object through a foreign key, but has not
1490
1546
  # yet been saved.
1491
- # [create_association(attributes = {})]
1547
+ # [<tt>create_association(attributes = {})</tt>]
1492
1548
  # Returns a new object of the associated type that has been instantiated
1493
1549
  # with +attributes+, linked to this object through a foreign key, and that
1494
1550
  # has already been saved (if it passed the validation).
1495
- # [create_association!(attributes = {})]
1551
+ # [<tt>create_association!(attributes = {})</tt>]
1496
1552
  # Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
1497
1553
  # if the record is invalid.
1498
- # [reload_association]
1554
+ # [<tt>reload_association</tt>]
1499
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):
1500
1566
  #
1501
- # === Example
1567
+ # account = Account.find(5)
1568
+ # beneficiary = Beneficiary.find(8)
1502
1569
  #
1503
- # An Account class declares <tt>has_one :beneficiary</tt>, which will add:
1504
- # * <tt>Account#beneficiary</tt> (similar to <tt>Beneficiary.where(account_id: id).first</tt>)
1505
- # * <tt>Account#beneficiary=(beneficiary)</tt> (similar to <tt>beneficiary.account_id = account.id; beneficiary.save</tt>)
1506
- # * <tt>Account#build_beneficiary</tt> (similar to <tt>Beneficiary.new(account_id: id)</tt>)
1507
- # * <tt>Account#create_beneficiary</tt> (similar to <tt>b = Beneficiary.new(account_id: id); b.save; b</tt>)
1508
- # * <tt>Account#create_beneficiary!</tt> (similar to <tt>b = Beneficiary.new(account_id: id); b.save!; b</tt>)
1509
- # * <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
1510
1577
  #
1511
- # === Scopes
1578
+ # ==== Scopes
1512
1579
  #
1513
1580
  # You can pass a second argument +scope+ as a callable (i.e. proc or
1514
1581
  # lambda) to retrieve a specific record or customize the generated query
@@ -1519,16 +1586,16 @@ module ActiveRecord
1519
1586
  # has_one :employer, -> { joins(:company) }
1520
1587
  # has_one :latest_post, ->(blog) { where("created_at > ?", blog.enabled_at) }
1521
1588
  #
1522
- # === Options
1589
+ # ==== Options
1523
1590
  #
1524
1591
  # The declaration can also include an +options+ hash to specialize the behavior of the association.
1525
1592
  #
1526
1593
  # Options are:
1527
- # [:class_name]
1594
+ # [+:class_name+]
1528
1595
  # Specify the class name of the association. Use it only if that name can't be inferred
1529
1596
  # from the association name. So <tt>has_one :manager</tt> will by default be linked to the Manager class, but
1530
1597
  # if the real class name is Person, you'll have to specify it with this option.
1531
- # [:dependent]
1598
+ # [+:dependent+]
1532
1599
  # Controls what happens to the associated object when
1533
1600
  # its owner is destroyed:
1534
1601
  #
@@ -1540,28 +1607,28 @@ module ActiveRecord
1540
1607
  # * <tt>:delete</tt> causes the associated object to be deleted directly from the database (so callbacks will not execute)
1541
1608
  # * <tt>:nullify</tt> causes the foreign key to be set to +NULL+. Polymorphic type column is also nullified
1542
1609
  # on polymorphic associations. Callbacks are not executed.
1543
- # * <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
1544
1611
  # * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there is an associated object
1545
1612
  #
1546
1613
  # Note that <tt>:dependent</tt> option is ignored when using <tt>:through</tt> option.
1547
- # [:foreign_key]
1614
+ # [+:foreign_key+]
1548
1615
  # Specify the foreign key used for the association. By default this is guessed to be the name
1549
1616
  # of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_one association
1550
1617
  # will use "person_id" as the default <tt>:foreign_key</tt>.
1551
1618
  #
1552
- # If you are going to modify the association (rather than just read from it), then it is
1553
- # a good idea to set the <tt>:inverse_of</tt> option.
1554
- # [: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+]
1555
1622
  # Specify the column used to store the associated object's type, if this is a polymorphic
1556
1623
  # association. By default this is guessed to be the name of the polymorphic association
1557
1624
  # specified on "as" option with a "_type" suffix. So a class that defines a
1558
1625
  # <tt>has_one :tag, as: :taggable</tt> association will use "taggable_type" as the
1559
1626
  # default <tt>:foreign_type</tt>.
1560
- # [:primary_key]
1627
+ # [+:primary_key+]
1561
1628
  # Specify the method that returns the primary key used for the association. By default this is +id+.
1562
- # [:as]
1629
+ # [+:as+]
1563
1630
  # Specifies a polymorphic interface (See #belongs_to).
1564
- # [:through]
1631
+ # [+:through+]
1565
1632
  # Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt>,
1566
1633
  # <tt>:primary_key</tt>, and <tt>:foreign_key</tt> are ignored, as the association uses the
1567
1634
  # source reflection. You can only use a <tt>:through</tt> query through a #has_one
@@ -1576,43 +1643,53 @@ module ActiveRecord
1576
1643
  # a good idea to set the <tt>:inverse_of</tt> option on the source association on the
1577
1644
  # join model. This allows associated records to be built which will automatically create
1578
1645
  # the appropriate join model records when they are saved. (See the 'Association Join Models'
1579
- # section above.)
1580
- # [:disable_joins]
1646
+ # and 'Setting Inverses' sections above.)
1647
+ # [+:disable_joins+]
1581
1648
  # Specifies whether joins should be skipped for an association. If set to true, two or more queries
1582
1649
  # will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory
1583
1650
  # due to database limitations. This option is only applicable on <tt>has_one :through</tt> associations as
1584
1651
  # +has_one+ alone does not perform a join.
1585
- # [:source]
1652
+ # [+:source+]
1586
1653
  # Specifies the source association name used by #has_one <tt>:through</tt> queries.
1587
1654
  # Only use it if the name cannot be inferred from the association.
1588
1655
  # <tt>has_one :favorite, through: :favorites</tt> will look for a
1589
1656
  # <tt>:favorite</tt> on Favorite, unless a <tt>:source</tt> is given.
1590
- # [:source_type]
1657
+ # [+:source_type+]
1591
1658
  # Specifies type of the source association used by #has_one <tt>:through</tt> queries where the source
1592
1659
  # association is a polymorphic #belongs_to.
1593
- # [:validate]
1660
+ # [+:validate+]
1594
1661
  # When set to +true+, validates new objects added to association when saving the parent object. +false+ by default.
1595
1662
  # If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
1596
- # [:autosave]
1663
+ # [+:autosave+]
1597
1664
  # If true, always save the associated object or destroy it if marked for destruction,
1598
1665
  # when saving the parent object. If false, never save or destroy the associated object.
1599
1666
  # By default, only save the associated object if it's a new record.
1600
1667
  #
1601
1668
  # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
1602
1669
  # <tt>:autosave</tt> to <tt>true</tt>.
1603
- # [: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+]
1604
1677
  # Specifies the name of the #belongs_to association on the associated object
1605
1678
  # that is the inverse of this #has_one association.
1606
1679
  # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1607
- # [:required]
1680
+ # [+:required+]
1608
1681
  # When set to +true+, the association will also have its presence validated.
1609
1682
  # This will validate the association itself, not the id. You can use
1610
1683
  # +:inverse_of+ to avoid an extra query during validation.
1611
- # [:strict_loading]
1684
+ # [+:strict_loading+]
1612
1685
  # Enforces strict loading every time the associated record is loaded through this association.
1613
- # [:ensuring_owner_was]
1686
+ # [+:ensuring_owner_was+]
1614
1687
  # Specifies an instance method to be called on the owner. The method must return true in order for the
1615
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.
1616
1693
  #
1617
1694
  # Option examples:
1618
1695
  # has_one :credit_card, dependent: :destroy # destroys the associated credit card
@@ -1627,6 +1704,7 @@ module ActiveRecord
1627
1704
  # has_one :primary_address, -> { where(primary: true) }, through: :addressables, source: :addressable
1628
1705
  # has_one :credit_card, required: true
1629
1706
  # has_one :credit_card, strict_loading: true
1707
+ # has_one :employment_record_book, query_constraints: [:organization_id, :employee_id]
1630
1708
  def has_one(name, scope = nil, **options)
1631
1709
  reflection = Builder::HasOne.build(self, name, scope, options)
1632
1710
  Reflection.add_reflection self, name, reflection
@@ -1643,42 +1721,52 @@ module ActiveRecord
1643
1721
  # +association+ is a placeholder for the symbol passed as the +name+ argument, so
1644
1722
  # <tt>belongs_to :author</tt> would add among others <tt>author.nil?</tt>.
1645
1723
  #
1646
- # [association]
1724
+ # [<tt>association</tt>]
1647
1725
  # Returns the associated object. +nil+ is returned if none is found.
1648
- # [association=(associate)]
1726
+ # [<tt>association=(associate)</tt>]
1649
1727
  # Assigns the associate object, extracts the primary key, and sets it as the foreign key.
1650
1728
  # No modification or deletion of existing records takes place.
1651
- # [build_association(attributes = {})]
1729
+ # [<tt>build_association(attributes = {})</tt>]
1652
1730
  # Returns a new object of the associated type that has been instantiated
1653
1731
  # with +attributes+ and linked to this object through a foreign key, but has not yet been saved.
1654
- # [create_association(attributes = {})]
1732
+ # [<tt>create_association(attributes = {})</tt>]
1655
1733
  # Returns a new object of the associated type that has been instantiated
1656
1734
  # with +attributes+, linked to this object through a foreign key, and that
1657
1735
  # has already been saved (if it passed the validation).
1658
- # [create_association!(attributes = {})]
1736
+ # [<tt>create_association!(attributes = {})</tt>]
1659
1737
  # Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
1660
1738
  # if the record is invalid.
1661
- # [reload_association]
1739
+ # [<tt>reload_association</tt>]
1662
1740
  # Returns the associated object, forcing a database read.
1663
- # [association_changed?]
1741
+ # [<tt>reset_association</tt>]
1742
+ # Unloads the associated object. The next access will query it from the database.
1743
+ # [<tt>association_changed?</tt>]
1664
1744
  # Returns true if a new associate object has been assigned and the next save will update the foreign key.
1665
- # [association_previously_changed?]
1745
+ # [<tt>association_previously_changed?</tt>]
1666
1746
  # Returns true if the previous save updated the association to reference a new associate object.
1667
1747
  #
1668
- # === Example
1669
- #
1670
- # A Post class declares <tt>belongs_to :author</tt>, which will add:
1671
- # * <tt>Post#author</tt> (similar to <tt>Author.find(author_id)</tt>)
1672
- # * <tt>Post#author=(author)</tt> (similar to <tt>post.author_id = author.id</tt>)
1673
- # * <tt>Post#build_author</tt> (similar to <tt>post.author = Author.new</tt>)
1674
- # * <tt>Post#create_author</tt> (similar to <tt>post.author = Author.new; post.author.save; post.author</tt>)
1675
- # * <tt>Post#create_author!</tt> (similar to <tt>post.author = Author.new; post.author.save!; post.author</tt>)
1676
- # * <tt>Post#reload_author</tt>
1677
- # * <tt>Post#author_changed?</tt>
1678
- # * <tt>Post#author_previously_changed?</tt>
1679
- # The declaration can also include an +options+ hash to specialize the behavior of the association.
1748
+ # ==== Example
1749
+ #
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):
1680
1755
  #
1681
- # === 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
1682
1770
  #
1683
1771
  # You can pass a second argument +scope+ as a callable (i.e. proc or
1684
1772
  # lambda) to retrieve a specific record or customize the generated query
@@ -1689,37 +1777,39 @@ module ActiveRecord
1689
1777
  # belongs_to :user, -> { joins(:friends) }
1690
1778
  # belongs_to :level, ->(game) { where("game_level > ?", game.current_level) }
1691
1779
  #
1692
- # === Options
1780
+ # ==== Options
1693
1781
  #
1694
- # [:class_name]
1782
+ # The declaration can also include an +options+ hash to specialize the behavior of the association.
1783
+ #
1784
+ # [+:class_name+]
1695
1785
  # Specify the class name of the association. Use it only if that name can't be inferred
1696
1786
  # from the association name. So <tt>belongs_to :author</tt> will by default be linked to the Author class, but
1697
1787
  # if the real class name is Person, you'll have to specify it with this option.
1698
- # [:foreign_key]
1788
+ # [+:foreign_key+]
1699
1789
  # Specify the foreign key used for the association. By default this is guessed to be the name
1700
1790
  # of the association with an "_id" suffix. So a class that defines a <tt>belongs_to :person</tt>
1701
1791
  # association will use "person_id" as the default <tt>:foreign_key</tt>. Similarly,
1702
1792
  # <tt>belongs_to :favorite_person, class_name: "Person"</tt> will use a foreign key
1703
1793
  # of "favorite_person_id".
1704
1794
  #
1705
- # If you are going to modify the association (rather than just read from it), then it is
1706
- # a good idea to set the <tt>:inverse_of</tt> option.
1707
- # [: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+]
1708
1798
  # Specify the column used to store the associated object's type, if this is a polymorphic
1709
1799
  # association. By default this is guessed to be the name of the association with a "_type"
1710
1800
  # suffix. So a class that defines a <tt>belongs_to :taggable, polymorphic: true</tt>
1711
1801
  # association will use "taggable_type" as the default <tt>:foreign_type</tt>.
1712
- # [:primary_key]
1802
+ # [+:primary_key+]
1713
1803
  # Specify the method that returns the primary key of associated object used for the association.
1714
1804
  # By default this is +id+.
1715
- # [:dependent]
1805
+ # [+:dependent+]
1716
1806
  # If set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to
1717
1807
  # <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method. If set to
1718
1808
  # <tt>:destroy_async</tt>, the associated object is scheduled to be destroyed in a background job.
1719
1809
  # This option should not be specified when #belongs_to is used in conjunction with
1720
1810
  # a #has_many relationship on another class because of the potential to leave
1721
1811
  # orphaned records behind.
1722
- # [:counter_cache]
1812
+ # [+:counter_cache+]
1723
1813
  # Caches the number of belonging objects on the associate class through the use of CounterCache::ClassMethods#increment_counter
1724
1814
  # and CounterCache::ClassMethods#decrement_counter. The counter cache is incremented when an object of this
1725
1815
  # class is created and decremented when it's destroyed. This requires that a column
@@ -1731,14 +1821,14 @@ module ActiveRecord
1731
1821
  # option (e.g., <tt>counter_cache: :my_custom_counter</tt>.)
1732
1822
  # Note: Specifying a counter cache will add it to that model's list of readonly attributes
1733
1823
  # using +attr_readonly+.
1734
- # [:polymorphic]
1824
+ # [+:polymorphic+]
1735
1825
  # Specify this association is a polymorphic association by passing +true+.
1736
1826
  # Note: If you've enabled the counter cache, then you may want to add the counter cache attribute
1737
1827
  # to the +attr_readonly+ list in the associated classes (e.g. <tt>class Post; attr_readonly :comments_count; end</tt>).
1738
- # [:validate]
1828
+ # [+:validate+]
1739
1829
  # When set to +true+, validates new objects added to association when saving the parent object. +false+ by default.
1740
1830
  # If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
1741
- # [:autosave]
1831
+ # [+:autosave+]
1742
1832
  # If true, always save the associated object or destroy it if marked for destruction, when
1743
1833
  # saving the parent object.
1744
1834
  # If false, never save or destroy the associated object.
@@ -1746,32 +1836,37 @@ module ActiveRecord
1746
1836
  #
1747
1837
  # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for
1748
1838
  # sets <tt>:autosave</tt> to <tt>true</tt>.
1749
- # [:touch]
1750
- # 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)
1751
1841
  # when this record is either saved or destroyed. If you specify a symbol, that attribute
1752
- # will be updated with the current time in addition to the updated_at/on attribute.
1753
- # Please note that with touching no validation is performed and only the +after_touch+,
1754
- # +after_commit+ and +after_rollback+ callbacks are executed.
1755
- # [: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+]
1756
1846
  # Specifies the name of the #has_one or #has_many association on the associated
1757
1847
  # object that is the inverse of this #belongs_to association.
1758
1848
  # See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
1759
- # [:optional]
1849
+ # [+:optional+]
1760
1850
  # When set to +true+, the association will not have its presence validated.
1761
- # [:required]
1851
+ # [+:required+]
1762
1852
  # When set to +true+, the association will also have its presence validated.
1763
1853
  # This will validate the association itself, not the id. You can use
1764
1854
  # +:inverse_of+ to avoid an extra query during validation.
1765
1855
  # NOTE: <tt>required</tt> is set to <tt>true</tt> by default and is deprecated. If
1766
1856
  # you don't want to have association presence validated, use <tt>optional: true</tt>.
1767
- # [:default]
1857
+ # [+:default+]
1768
1858
  # Provide a callable (i.e. proc or lambda) to specify that the association should
1769
1859
  # be initialized with a particular record before validation.
1770
- # [:strict_loading]
1860
+ # Please note that callable won't be executed if the record exists.
1861
+ # [+:strict_loading+]
1771
1862
  # Enforces strict loading every time the associated record is loaded through this association.
1772
- # [:ensuring_owner_was]
1863
+ # [+:ensuring_owner_was+]
1773
1864
  # Specifies an instance method to be called on the owner. The method must return true in order for the
1774
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.
1775
1870
  #
1776
1871
  # Option examples:
1777
1872
  # belongs_to :firm, foreign_key: "client_of"
@@ -1787,6 +1882,7 @@ module ActiveRecord
1787
1882
  # belongs_to :user, optional: true
1788
1883
  # belongs_to :account, default: -> { company.account }
1789
1884
  # belongs_to :account, strict_loading: true
1885
+ # belong_to :note, query_constraints: [:organization_id, :note_id]
1790
1886
  def belongs_to(name, scope = nil, **options)
1791
1887
  reflection = Builder::BelongsTo.build(self, name, scope, options)
1792
1888
  Reflection.add_reflection self, name, reflection
@@ -1809,7 +1905,7 @@ module ActiveRecord
1809
1905
  # The join table should not have a primary key or a model associated with it. You must manually generate the
1810
1906
  # join table with a migration such as this:
1811
1907
  #
1812
- # class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration[7.0]
1908
+ # class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration[7.1]
1813
1909
  # def change
1814
1910
  # create_join_table :developers, :projects
1815
1911
  # end
@@ -1824,71 +1920,80 @@ module ActiveRecord
1824
1920
  # +collection+ is a placeholder for the symbol passed as the +name+ argument, so
1825
1921
  # <tt>has_and_belongs_to_many :categories</tt> would add among others <tt>categories.empty?</tt>.
1826
1922
  #
1827
- # [collection]
1923
+ # [<tt>collection</tt>]
1828
1924
  # Returns a Relation of all the associated objects.
1829
1925
  # An empty Relation is returned if none are found.
1830
- # [collection<<(object, ...)]
1926
+ # [<tt>collection<<(object, ...)</tt>]
1831
1927
  # Adds one or more objects to the collection by creating associations in the join table
1832
1928
  # (<tt>collection.push</tt> and <tt>collection.concat</tt> are aliases to this method).
1833
1929
  # Note that this operation instantly fires update SQL without waiting for the save or update call on the
1834
1930
  # parent object, unless the parent object is a new record.
1835
- # [collection.delete(object, ...)]
1931
+ # [<tt>collection.delete(object, ...)</tt>]
1836
1932
  # Removes one or more objects from the collection by removing their associations from the join table.
1837
1933
  # This does not destroy the objects.
1838
- # [collection.destroy(object, ...)]
1934
+ # [<tt>collection.destroy(object, ...)</tt>]
1839
1935
  # Removes one or more objects from the collection by running destroy on each association in the join table, overriding any dependent option.
1840
1936
  # This does not destroy the objects.
1841
- # [collection=objects]
1937
+ # [<tt>collection=objects</tt>]
1842
1938
  # Replaces the collection's content by deleting and adding objects as appropriate.
1843
- # [collection_singular_ids]
1939
+ # [<tt>collection_singular_ids</tt>]
1844
1940
  # Returns an array of the associated objects' ids.
1845
- # [collection_singular_ids=ids]
1941
+ # [<tt>collection_singular_ids=ids</tt>]
1846
1942
  # Replace the collection by the objects identified by the primary keys in +ids+.
1847
- # [collection.clear]
1943
+ # [<tt>collection.clear</tt>]
1848
1944
  # Removes every object from the collection. This does not destroy the objects.
1849
- # [collection.empty?]
1945
+ # [<tt>collection.empty?</tt>]
1850
1946
  # Returns +true+ if there are no associated objects.
1851
- # [collection.size]
1947
+ # [<tt>collection.size</tt>]
1852
1948
  # Returns the number of associated objects.
1853
- # [collection.find(id)]
1949
+ # [<tt>collection.find(id)</tt>]
1854
1950
  # Finds an associated object responding to the +id+ and that
1855
1951
  # meets the condition that it has to be associated with this object.
1856
1952
  # Uses the same rules as ActiveRecord::FinderMethods#find.
1857
- # [collection.exists?(...)]
1953
+ # [<tt>collection.exists?(...)</tt>]
1858
1954
  # Checks whether an associated object with the given conditions exists.
1859
1955
  # Uses the same rules as ActiveRecord::FinderMethods#exists?.
1860
- # [collection.build(attributes = {})]
1956
+ # [<tt>collection.build(attributes = {})</tt>]
1861
1957
  # Returns a new object of the collection type that has been instantiated
1862
1958
  # with +attributes+ and linked to this object through the join table, but has not yet been saved.
1863
- # [collection.create(attributes = {})]
1959
+ # [<tt>collection.create(attributes = {})</tt>]
1864
1960
  # Returns a new object of the collection type that has been instantiated
1865
1961
  # with +attributes+, linked to this object through the join table, and that has already been
1866
1962
  # saved (if it passed the validation).
1867
- # [collection.reload]
1963
+ # [<tt>collection.reload</tt>]
1868
1964
  # Returns a Relation of all of the associated objects, forcing a database read.
1869
1965
  # An empty Relation is returned if none are found.
1870
1966
  #
1871
- # === Example
1872
- #
1873
- # A Developer class declares <tt>has_and_belongs_to_many :projects</tt>, which will add:
1874
- # * <tt>Developer#projects</tt>
1875
- # * <tt>Developer#projects<<</tt>
1876
- # * <tt>Developer#projects.delete</tt>
1877
- # * <tt>Developer#projects.destroy</tt>
1878
- # * <tt>Developer#projects=</tt>
1879
- # * <tt>Developer#project_ids</tt>
1880
- # * <tt>Developer#project_ids=</tt>
1881
- # * <tt>Developer#projects.clear</tt>
1882
- # * <tt>Developer#projects.empty?</tt>
1883
- # * <tt>Developer#projects.size</tt>
1884
- # * <tt>Developer#projects.find(id)</tt>
1885
- # * <tt>Developer#projects.exists?(...)</tt>
1886
- # * <tt>Developer#projects.build</tt> (similar to <tt>Project.new(developer_id: id)</tt>)
1887
- # * <tt>Developer#projects.create</tt> (similar to <tt>c = Project.new(developer_id: id); c.save; c</tt>)
1888
- # * <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
+ #
1889
1994
  # The declaration may include an +options+ hash to specialize the behavior of the association.
1890
1995
  #
1891
- # === Scopes
1996
+ # ==== Scopes
1892
1997
  #
1893
1998
  # You can pass a second argument +scope+ as a callable (i.e. proc or
1894
1999
  # lambda) to retrieve a specific set of records or customize the generated
@@ -1900,7 +2005,7 @@ module ActiveRecord
1900
2005
  # where("default_category = ?", post.default_category)
1901
2006
  # }
1902
2007
  #
1903
- # === Extensions
2008
+ # ==== Extensions
1904
2009
  #
1905
2010
  # The +extension+ argument allows you to pass a block into a
1906
2011
  # has_and_belongs_to_many association. This is useful for adding new
@@ -1915,33 +2020,33 @@ module ActiveRecord
1915
2020
  # end
1916
2021
  # end
1917
2022
  #
1918
- # === Options
2023
+ # ==== Options
1919
2024
  #
1920
- # [:class_name]
2025
+ # [+:class_name+]
1921
2026
  # Specify the class name of the association. Use it only if that name can't be inferred
1922
2027
  # from the association name. So <tt>has_and_belongs_to_many :projects</tt> will by default be linked to the
1923
2028
  # Project class, but if the real class name is SuperProject, you'll have to specify it with this option.
1924
- # [:join_table]
2029
+ # [+:join_table+]
1925
2030
  # Specify the name of the join table if the default based on lexical order isn't what you want.
1926
2031
  # <b>WARNING:</b> If you're overwriting the table name of either class, the +table_name+ method
1927
2032
  # MUST be declared underneath any #has_and_belongs_to_many declaration in order to work.
1928
- # [:foreign_key]
2033
+ # [+:foreign_key+]
1929
2034
  # Specify the foreign key used for the association. By default this is guessed to be the name
1930
2035
  # of this class in lower-case and "_id" suffixed. So a Person class that makes
1931
2036
  # a #has_and_belongs_to_many association to Project will use "person_id" as the
1932
2037
  # default <tt>:foreign_key</tt>.
1933
2038
  #
1934
- # If you are going to modify the association (rather than just read from it), then it is
1935
- # a good idea to set the <tt>:inverse_of</tt> option.
1936
- # [: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+]
1937
2042
  # Specify the foreign key used for the association on the receiving side of the association.
1938
2043
  # By default this is guessed to be the name of the associated class in lower-case and "_id" suffixed.
1939
2044
  # So if a Person class makes a #has_and_belongs_to_many association to Project,
1940
2045
  # the association will use "project_id" as the default <tt>:association_foreign_key</tt>.
1941
- # [:validate]
2046
+ # [+:validate+]
1942
2047
  # When set to +true+, validates new objects added to association when saving the parent object. +true+ by default.
1943
2048
  # If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
1944
- # [:autosave]
2049
+ # [+:autosave+]
1945
2050
  # If true, always save the associated objects or destroy them if marked for destruction, when
1946
2051
  # saving the parent object.
1947
2052
  # If false, never save or destroy the associated objects.
@@ -1949,7 +2054,7 @@ module ActiveRecord
1949
2054
  #
1950
2055
  # Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
1951
2056
  # <tt>:autosave</tt> to <tt>true</tt>.
1952
- # [:strict_loading]
2057
+ # [+:strict_loading+]
1953
2058
  # Enforces strict loading every time an associated record is loaded through this association.
1954
2059
  #
1955
2060
  # Option examples: