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