activerecord 7.0.0 → 7.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1701 -1039
- data/MIT-LICENSE +1 -1
- data/README.rdoc +18 -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 +362 -236
- 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 +52 -34
- 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 +129 -31
- 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 -131
- data/lib/active_record/connection_adapters/abstract/transaction.rb +287 -58
- data/lib/active_record/connection_adapters/abstract_adapter.rb +513 -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 +151 -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 +16 -3
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +75 -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/money.rb +3 -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 +4 -2
- 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 +372 -63
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +359 -197
- 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 +52 -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 +99 -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 +142 -153
- 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 -86
- 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 +113 -29
- 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 +3 -3
- data/lib/active_record/inheritance.rb +30 -16
- data/lib/active_record/insert_all.rb +57 -10
- data/lib/active_record/integration.rb +10 -10
- data/lib/active_record/internal_metadata.rb +120 -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 +108 -10
- 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/pending_migration_connection.rb +21 -0
- data/lib/active_record/migration.rb +274 -117
- data/lib/active_record/model_schema.rb +86 -54
- data/lib/active_record/nested_attributes.rb +24 -6
- data/lib/active_record/normalization.rb +167 -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 +128 -62
- data/lib/active_record/railties/controller_runtime.rb +12 -8
- data/lib/active_record/railties/databases.rake +145 -146
- 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 +189 -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 +208 -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 +430 -77
- 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 +27 -15
- 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 +1 -9
- 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 +51 -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,75 +1292,84 @@ module ActiveRecord
|
|
1229
1292
|
# If the <tt>:through</tt> option is used, then the join records are deleted (rather than
|
1230
1293
|
# nullified) by default, but you can specify <tt>dependent: :destroy</tt> or
|
1231
1294
|
# <tt>dependent: :nullify</tt> to override this.
|
1232
|
-
# [collection.destroy(object, ...)]
|
1295
|
+
# [<tt>collection.destroy(object, ...)</tt>]
|
1233
1296
|
# Removes one or more objects from the collection by running <tt>destroy</tt> on
|
1234
1297
|
# each record, regardless of any dependent option, ensuring callbacks are run.
|
1235
1298
|
#
|
1236
1299
|
# If the <tt>:through</tt> option is used, then the join records are destroyed
|
1237
1300
|
# instead, not the objects themselves.
|
1238
|
-
# [collection=objects]
|
1301
|
+
# [<tt>collection=objects</tt>]
|
1239
1302
|
# Replaces the collections content by deleting and adding objects as appropriate. If the <tt>:through</tt>
|
1240
1303
|
# option is true callbacks in the join models are triggered except destroy callbacks, since deletion is
|
1241
1304
|
# direct by default. You can specify <tt>dependent: :destroy</tt> or
|
1242
1305
|
# <tt>dependent: :nullify</tt> to override this.
|
1243
|
-
# [collection_singular_ids]
|
1306
|
+
# [<tt>collection_singular_ids</tt>]
|
1244
1307
|
# Returns an array of the associated objects' ids
|
1245
|
-
# [collection_singular_ids=ids]
|
1308
|
+
# [<tt>collection_singular_ids=ids</tt>]
|
1246
1309
|
# Replace the collection with the objects identified by the primary keys in +ids+. This
|
1247
1310
|
# method loads the models and calls <tt>collection=</tt>. See above.
|
1248
|
-
# [collection.clear]
|
1311
|
+
# [<tt>collection.clear</tt>]
|
1249
1312
|
# Removes every object from the collection. This destroys the associated objects if they
|
1250
1313
|
# are associated with <tt>dependent: :destroy</tt>, deletes them directly from the
|
1251
1314
|
# database if <tt>dependent: :delete_all</tt>, otherwise sets their foreign keys to +NULL+.
|
1252
1315
|
# If the <tt>:through</tt> option is true no destroy callbacks are invoked on the join models.
|
1253
1316
|
# Join models are directly deleted.
|
1254
|
-
# [collection.empty
|
1317
|
+
# [<tt>collection.empty?</tt>]
|
1255
1318
|
# Returns +true+ if there are no associated objects.
|
1256
|
-
# [collection.size]
|
1319
|
+
# [<tt>collection.size</tt>]
|
1257
1320
|
# Returns the number of associated objects.
|
1258
|
-
# [collection.find(...)]
|
1321
|
+
# [<tt>collection.find(...)</tt>]
|
1259
1322
|
# Finds an associated object according to the same rules as ActiveRecord::FinderMethods#find.
|
1260
|
-
# [collection.exists?(...)]
|
1323
|
+
# [<tt>collection.exists?(...)</tt>]
|
1261
1324
|
# Checks whether an associated object with the given conditions exists.
|
1262
1325
|
# Uses the same rules as ActiveRecord::FinderMethods#exists?.
|
1263
|
-
# [collection.build(attributes = {}, ...)]
|
1326
|
+
# [<tt>collection.build(attributes = {}, ...)</tt>]
|
1264
1327
|
# Returns one or more new objects of the collection type that have been instantiated
|
1265
1328
|
# with +attributes+ and linked to this object through a foreign key, but have not yet
|
1266
1329
|
# been saved.
|
1267
|
-
# [collection.create(attributes = {})]
|
1330
|
+
# [<tt>collection.create(attributes = {})</tt>]
|
1268
1331
|
# Returns a new object of the collection type that has been instantiated
|
1269
1332
|
# with +attributes+, linked to this object through a foreign key, and that has already
|
1270
1333
|
# been saved (if it passed the validation). *Note*: This only works if the base model
|
1271
1334
|
# already exists in the DB, not if it is a new (unsaved) record!
|
1272
|
-
# [collection.create!(attributes = {})]
|
1335
|
+
# [<tt>collection.create!(attributes = {})</tt>]
|
1273
1336
|
# Does the same as <tt>collection.create</tt>, but raises ActiveRecord::RecordInvalid
|
1274
1337
|
# if the record is invalid.
|
1275
|
-
# [collection.reload]
|
1338
|
+
# [<tt>collection.reload</tt>]
|
1276
1339
|
# Returns a Relation of all of the associated objects, forcing a database read.
|
1277
1340
|
# An empty Relation is returned if none are found.
|
1278
1341
|
#
|
1279
|
-
#
|
1280
|
-
#
|
1281
|
-
#
|
1282
|
-
#
|
1283
|
-
#
|
1284
|
-
#
|
1285
|
-
#
|
1286
|
-
#
|
1287
|
-
#
|
1288
|
-
#
|
1289
|
-
#
|
1290
|
-
#
|
1291
|
-
#
|
1292
|
-
#
|
1293
|
-
#
|
1294
|
-
#
|
1295
|
-
#
|
1296
|
-
#
|
1297
|
-
#
|
1342
|
+
# ==== Example
|
1343
|
+
#
|
1344
|
+
# class Firm < ActiveRecord::Base
|
1345
|
+
# has_many :clients
|
1346
|
+
# end
|
1347
|
+
#
|
1348
|
+
# Declaring <tt>has_many :clients</tt> adds the following methods (and more):
|
1349
|
+
#
|
1350
|
+
# firm = Firm.find(2)
|
1351
|
+
# client = Client.find(6)
|
1352
|
+
#
|
1353
|
+
# firm.clients # similar to Client.where(firm_id: 2)
|
1354
|
+
# firm.clients << client
|
1355
|
+
# firm.clients.delete(client)
|
1356
|
+
# firm.clients.destroy(client)
|
1357
|
+
# firm.clients = [client]
|
1358
|
+
# firm.client_ids
|
1359
|
+
# firm.client_ids = [6]
|
1360
|
+
# firm.clients.clear
|
1361
|
+
# firm.clients.empty? # similar to firm.clients.size == 0
|
1362
|
+
# firm.clients.size # similar to Client.count "firm_id = 2"
|
1363
|
+
# firm.clients.find # similar to Client.where(firm_id: 2).find(6)
|
1364
|
+
# firm.clients.exists?(name: 'ACME') # similar to Client.exists?(name: 'ACME', firm_id: 2)
|
1365
|
+
# firm.clients.build # similar to Client.new(firm_id: 2)
|
1366
|
+
# firm.clients.create # similar to Client.create(firm_id: 2)
|
1367
|
+
# firm.clients.create! # similar to Client.create!(firm_id: 2)
|
1368
|
+
# firm.clients.reload
|
1369
|
+
#
|
1298
1370
|
# The declaration can also include an +options+ hash to specialize the behavior of the association.
|
1299
1371
|
#
|
1300
|
-
#
|
1372
|
+
# ==== Scopes
|
1301
1373
|
#
|
1302
1374
|
# You can pass a second argument +scope+ as a callable (i.e. proc or
|
1303
1375
|
# lambda) to retrieve a specific set of records or customize the generated
|
@@ -1308,10 +1380,10 @@ module ActiveRecord
|
|
1308
1380
|
# has_many :employees, -> { joins(:address) }
|
1309
1381
|
# has_many :posts, ->(blog) { where("max_post_length > ?", blog.max_post_length) }
|
1310
1382
|
#
|
1311
|
-
#
|
1383
|
+
# ==== Extensions
|
1312
1384
|
#
|
1313
1385
|
# The +extension+ argument allows you to pass a block into a has_many
|
1314
|
-
# association. This is useful for adding new finders, creators and other
|
1386
|
+
# association. This is useful for adding new finders, creators, and other
|
1315
1387
|
# factory-type methods to be used as part of the association.
|
1316
1388
|
#
|
1317
1389
|
# Extension examples:
|
@@ -1322,31 +1394,31 @@ module ActiveRecord
|
|
1322
1394
|
# end
|
1323
1395
|
# end
|
1324
1396
|
#
|
1325
|
-
#
|
1326
|
-
# [
|
1397
|
+
# ==== Options
|
1398
|
+
# [+:class_name+]
|
1327
1399
|
# Specify the class name of the association. Use it only if that name can't be inferred
|
1328
1400
|
# from the association name. So <tt>has_many :products</tt> will by default be linked
|
1329
1401
|
# to the +Product+ class, but if the real class name is +SpecialProduct+, you'll have to
|
1330
1402
|
# specify it with this option.
|
1331
|
-
# [
|
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,37 +1534,48 @@ module ActiveRecord
|
|
1457
1534
|
# +association+ is a placeholder for the symbol passed as the +name+ argument, so
|
1458
1535
|
# <tt>has_one :manager</tt> would add among others <tt>manager.nil?</tt>.
|
1459
1536
|
#
|
1460
|
-
# [association]
|
1537
|
+
# [<tt>association</tt>]
|
1461
1538
|
# Returns the associated object. +nil+ is returned if none is found.
|
1462
|
-
# [association=(associate)]
|
1539
|
+
# [<tt>association=(associate)</tt>]
|
1463
1540
|
# Assigns the associate object, extracts the primary key, sets it as the foreign key,
|
1464
1541
|
# and saves the associate object. To avoid database inconsistencies, permanently deletes an existing
|
1465
1542
|
# associated object when assigning a new one, even if the new one isn't saved to database.
|
1466
|
-
# [build_association(attributes = {})]
|
1543
|
+
# [<tt>build_association(attributes = {})</tt>]
|
1467
1544
|
# Returns a new object of the associated type that has been instantiated
|
1468
1545
|
# with +attributes+ and linked to this object through a foreign key, but has not
|
1469
1546
|
# yet been saved.
|
1470
|
-
# [create_association(attributes = {})]
|
1547
|
+
# [<tt>create_association(attributes = {})</tt>]
|
1471
1548
|
# Returns a new object of the associated type that has been instantiated
|
1472
1549
|
# with +attributes+, linked to this object through a foreign key, and that
|
1473
1550
|
# has already been saved (if it passed the validation).
|
1474
|
-
# [create_association!(attributes = {})]
|
1551
|
+
# [<tt>create_association!(attributes = {})</tt>]
|
1475
1552
|
# Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
|
1476
1553
|
# if the record is invalid.
|
1477
|
-
# [reload_association]
|
1554
|
+
# [<tt>reload_association</tt>]
|
1478
1555
|
# Returns the associated object, forcing a database read.
|
1556
|
+
# [<tt>reset_association</tt>]
|
1557
|
+
# Unloads the associated object. The next access will query it from the database.
|
1558
|
+
#
|
1559
|
+
# ==== Example
|
1560
|
+
#
|
1561
|
+
# class Account < ActiveRecord::Base
|
1562
|
+
# has_one :beneficiary
|
1563
|
+
# end
|
1564
|
+
#
|
1565
|
+
# Declaring <tt>has_one :beneficiary</tt> adds the following methods (and more):
|
1479
1566
|
#
|
1480
|
-
#
|
1567
|
+
# account = Account.find(5)
|
1568
|
+
# beneficiary = Beneficiary.find(8)
|
1481
1569
|
#
|
1482
|
-
#
|
1483
|
-
#
|
1484
|
-
#
|
1485
|
-
#
|
1486
|
-
#
|
1487
|
-
#
|
1488
|
-
#
|
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
|
#
|
1492
1580
|
# You can pass a second argument +scope+ as a callable (i.e. proc or
|
1493
1581
|
# lambda) to retrieve a specific record or customize the generated query
|
@@ -1498,16 +1586,16 @@ module ActiveRecord
|
|
1498
1586
|
# has_one :employer, -> { joins(:company) }
|
1499
1587
|
# has_one :latest_post, ->(blog) { where("created_at > ?", blog.enabled_at) }
|
1500
1588
|
#
|
1501
|
-
#
|
1589
|
+
# ==== Options
|
1502
1590
|
#
|
1503
1591
|
# The declaration can also include an +options+ hash to specialize the behavior of the association.
|
1504
1592
|
#
|
1505
1593
|
# Options are:
|
1506
|
-
# [
|
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,42 +1721,52 @@ module ActiveRecord
|
|
1622
1721
|
# +association+ is a placeholder for the symbol passed as the +name+ argument, so
|
1623
1722
|
# <tt>belongs_to :author</tt> would add among others <tt>author.nil?</tt>.
|
1624
1723
|
#
|
1625
|
-
# [association]
|
1724
|
+
# [<tt>association</tt>]
|
1626
1725
|
# Returns the associated object. +nil+ is returned if none is found.
|
1627
|
-
# [association=(associate)]
|
1726
|
+
# [<tt>association=(associate)</tt>]
|
1628
1727
|
# Assigns the associate object, extracts the primary key, and sets it as the foreign key.
|
1629
1728
|
# No modification or deletion of existing records takes place.
|
1630
|
-
# [build_association(attributes = {})]
|
1729
|
+
# [<tt>build_association(attributes = {})</tt>]
|
1631
1730
|
# Returns a new object of the associated type that has been instantiated
|
1632
1731
|
# with +attributes+ and linked to this object through a foreign key, but has not yet been saved.
|
1633
|
-
# [create_association(attributes = {})]
|
1732
|
+
# [<tt>create_association(attributes = {})</tt>]
|
1634
1733
|
# Returns a new object of the associated type that has been instantiated
|
1635
1734
|
# with +attributes+, linked to this object through a foreign key, and that
|
1636
1735
|
# has already been saved (if it passed the validation).
|
1637
|
-
# [create_association!(attributes = {})]
|
1736
|
+
# [<tt>create_association!(attributes = {})</tt>]
|
1638
1737
|
# Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
|
1639
1738
|
# if the record is invalid.
|
1640
|
-
# [reload_association]
|
1739
|
+
# [<tt>reload_association</tt>]
|
1641
1740
|
# Returns the associated object, forcing a database read.
|
1642
|
-
# [
|
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
|
-
#
|
1648
|
-
#
|
1649
|
-
#
|
1650
|
-
#
|
1651
|
-
#
|
1652
|
-
#
|
1653
|
-
#
|
1654
|
-
#
|
1655
|
-
#
|
1656
|
-
#
|
1657
|
-
# * <tt>Post#author_previously_changed?</tt>
|
1658
|
-
# The declaration can also include an +options+ hash to specialize the behavior of the association.
|
1748
|
+
# ==== Example
|
1749
|
+
#
|
1750
|
+
# class Post < ActiveRecord::Base
|
1751
|
+
# belongs_to :author
|
1752
|
+
# end
|
1753
|
+
#
|
1754
|
+
# Declaring <tt>belongs_to :author</tt> adds the following methods (and more):
|
1755
|
+
#
|
1756
|
+
# post = Post.find(7)
|
1757
|
+
# author = Author.find(19)
|
1659
1758
|
#
|
1660
|
-
#
|
1759
|
+
# post.author # similar to Author.find(post.author_id)
|
1760
|
+
# post.author = author # similar to post.author_id = author.id
|
1761
|
+
# post.build_author # similar to post.author = Author.new
|
1762
|
+
# post.create_author # similar to post.author = Author.new; post.author.save; post.author
|
1763
|
+
# post.create_author! # similar to post.author = Author.new; post.author.save!; post.author
|
1764
|
+
# post.reload_author
|
1765
|
+
# post.reset_author
|
1766
|
+
# post.author_changed?
|
1767
|
+
# post.author_previously_changed?
|
1768
|
+
#
|
1769
|
+
# ==== Scopes
|
1661
1770
|
#
|
1662
1771
|
# You can pass a second argument +scope+ as a callable (i.e. proc or
|
1663
1772
|
# lambda) to retrieve a specific record or customize the generated query
|
@@ -1668,37 +1777,39 @@ module ActiveRecord
|
|
1668
1777
|
# belongs_to :user, -> { joins(:friends) }
|
1669
1778
|
# belongs_to :level, ->(game) { where("game_level > ?", game.current_level) }
|
1670
1779
|
#
|
1671
|
-
#
|
1780
|
+
# ==== Options
|
1781
|
+
#
|
1782
|
+
# The declaration can also include an +options+ hash to specialize the behavior of the association.
|
1672
1783
|
#
|
1673
|
-
# [
|
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,71 +1920,80 @@ module ActiveRecord
|
|
1803
1920
|
# +collection+ is a placeholder for the symbol passed as the +name+ argument, so
|
1804
1921
|
# <tt>has_and_belongs_to_many :categories</tt> would add among others <tt>categories.empty?</tt>.
|
1805
1922
|
#
|
1806
|
-
# [collection]
|
1923
|
+
# [<tt>collection</tt>]
|
1807
1924
|
# Returns a Relation of all the associated objects.
|
1808
1925
|
# An empty Relation is returned if none are found.
|
1809
|
-
# [collection<<(object, ...)]
|
1926
|
+
# [<tt>collection<<(object, ...)</tt>]
|
1810
1927
|
# Adds one or more objects to the collection by creating associations in the join table
|
1811
1928
|
# (<tt>collection.push</tt> and <tt>collection.concat</tt> are aliases to this method).
|
1812
1929
|
# Note that this operation instantly fires update SQL without waiting for the save or update call on the
|
1813
1930
|
# parent object, unless the parent object is a new record.
|
1814
|
-
# [collection.delete(object, ...)]
|
1931
|
+
# [<tt>collection.delete(object, ...)</tt>]
|
1815
1932
|
# Removes one or more objects from the collection by removing their associations from the join table.
|
1816
1933
|
# This does not destroy the objects.
|
1817
|
-
# [collection.destroy(object, ...)]
|
1934
|
+
# [<tt>collection.destroy(object, ...)</tt>]
|
1818
1935
|
# Removes one or more objects from the collection by running destroy on each association in the join table, overriding any dependent option.
|
1819
1936
|
# This does not destroy the objects.
|
1820
|
-
# [collection=objects]
|
1937
|
+
# [<tt>collection=objects</tt>]
|
1821
1938
|
# Replaces the collection's content by deleting and adding objects as appropriate.
|
1822
|
-
# [collection_singular_ids]
|
1939
|
+
# [<tt>collection_singular_ids</tt>]
|
1823
1940
|
# Returns an array of the associated objects' ids.
|
1824
|
-
# [collection_singular_ids=ids]
|
1941
|
+
# [<tt>collection_singular_ids=ids</tt>]
|
1825
1942
|
# Replace the collection by the objects identified by the primary keys in +ids+.
|
1826
|
-
# [collection.clear]
|
1943
|
+
# [<tt>collection.clear</tt>]
|
1827
1944
|
# Removes every object from the collection. This does not destroy the objects.
|
1828
|
-
# [collection.empty
|
1945
|
+
# [<tt>collection.empty?</tt>]
|
1829
1946
|
# Returns +true+ if there are no associated objects.
|
1830
|
-
# [collection.size]
|
1947
|
+
# [<tt>collection.size</tt>]
|
1831
1948
|
# Returns the number of associated objects.
|
1832
|
-
# [collection.find(id)]
|
1949
|
+
# [<tt>collection.find(id)</tt>]
|
1833
1950
|
# Finds an associated object responding to the +id+ and that
|
1834
1951
|
# meets the condition that it has to be associated with this object.
|
1835
1952
|
# Uses the same rules as ActiveRecord::FinderMethods#find.
|
1836
|
-
# [collection.exists?(...)]
|
1953
|
+
# [<tt>collection.exists?(...)</tt>]
|
1837
1954
|
# Checks whether an associated object with the given conditions exists.
|
1838
1955
|
# Uses the same rules as ActiveRecord::FinderMethods#exists?.
|
1839
|
-
# [collection.build(attributes = {})]
|
1956
|
+
# [<tt>collection.build(attributes = {})</tt>]
|
1840
1957
|
# Returns a new object of the collection type that has been instantiated
|
1841
1958
|
# with +attributes+ and linked to this object through the join table, but has not yet been saved.
|
1842
|
-
# [collection.create(attributes = {})]
|
1959
|
+
# [<tt>collection.create(attributes = {})</tt>]
|
1843
1960
|
# Returns a new object of the collection type that has been instantiated
|
1844
1961
|
# with +attributes+, linked to this object through the join table, and that has already been
|
1845
1962
|
# saved (if it passed the validation).
|
1846
|
-
# [collection.reload]
|
1963
|
+
# [<tt>collection.reload</tt>]
|
1847
1964
|
# Returns a Relation of all of the associated objects, forcing a database read.
|
1848
1965
|
# An empty Relation is returned if none are found.
|
1849
1966
|
#
|
1850
|
-
#
|
1851
|
-
#
|
1852
|
-
#
|
1853
|
-
#
|
1854
|
-
#
|
1855
|
-
#
|
1856
|
-
#
|
1857
|
-
#
|
1858
|
-
#
|
1859
|
-
#
|
1860
|
-
#
|
1861
|
-
#
|
1862
|
-
#
|
1863
|
-
#
|
1864
|
-
#
|
1865
|
-
#
|
1866
|
-
#
|
1867
|
-
#
|
1967
|
+
# ==== Example
|
1968
|
+
#
|
1969
|
+
# class Developer < ActiveRecord::Base
|
1970
|
+
# has_and_belongs_to_many :projects
|
1971
|
+
# end
|
1972
|
+
#
|
1973
|
+
# Declaring <tt>has_and_belongs_to_many :projects</tt> adds the following methods (and more):
|
1974
|
+
#
|
1975
|
+
# developer = Developer.find(11)
|
1976
|
+
# project = Project.find(9)
|
1977
|
+
#
|
1978
|
+
# developer.projects
|
1979
|
+
# developer.projects << project
|
1980
|
+
# developer.projects.delete(project)
|
1981
|
+
# developer.projects.destroy(project)
|
1982
|
+
# developer.projects = [project]
|
1983
|
+
# developer.project_ids
|
1984
|
+
# developer.project_ids = [9]
|
1985
|
+
# developer.projects.clear
|
1986
|
+
# developer.projects.empty?
|
1987
|
+
# developer.projects.size
|
1988
|
+
# developer.projects.find(9)
|
1989
|
+
# developer.projects.exists?(9)
|
1990
|
+
# developer.projects.build # similar to Project.new(developer_id: 11)
|
1991
|
+
# developer.projects.create # similar to Project.create(developer_id: 11)
|
1992
|
+
# developer.projects.reload
|
1993
|
+
#
|
1868
1994
|
# The declaration may include an +options+ hash to specialize the behavior of the association.
|
1869
1995
|
#
|
1870
|
-
#
|
1996
|
+
# ==== Scopes
|
1871
1997
|
#
|
1872
1998
|
# You can pass a second argument +scope+ as a callable (i.e. proc or
|
1873
1999
|
# lambda) to retrieve a specific set of records or customize the generated
|
@@ -1879,11 +2005,11 @@ module ActiveRecord
|
|
1879
2005
|
# where("default_category = ?", post.default_category)
|
1880
2006
|
# }
|
1881
2007
|
#
|
1882
|
-
#
|
2008
|
+
# ==== Extensions
|
1883
2009
|
#
|
1884
2010
|
# The +extension+ argument allows you to pass a block into a
|
1885
2011
|
# has_and_belongs_to_many association. This is useful for adding new
|
1886
|
-
# finders, creators and other factory-type methods to be used as part of
|
2012
|
+
# finders, creators, and other factory-type methods to be used as part of
|
1887
2013
|
# the association.
|
1888
2014
|
#
|
1889
2015
|
# Extension examples:
|
@@ -1894,33 +2020,33 @@ module ActiveRecord
|
|
1894
2020
|
# end
|
1895
2021
|
# end
|
1896
2022
|
#
|
1897
|
-
#
|
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:
|