activerecord 7.0.0 → 7.1.2

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