activerecord 7.0.8.1 → 7.2.2.1

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