activerecord 7.0.8 → 7.1.0

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