activerecord 7.0.4 → 7.1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1971 -1243
- 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 +20 -4
- 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 +20 -14
- data/lib/active_record/associations/collection_proxy.rb +20 -10
- data/lib/active_record/associations/foreign_association.rb +10 -3
- data/lib/active_record/associations/has_many_association.rb +20 -13
- 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/join_association.rb +3 -2
- data/lib/active_record/associations/join_dependency.rb +10 -10
- data/lib/active_record/associations/preloader/association.rb +31 -7
- 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 +333 -222
- 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 +53 -35
- 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 +21 -8
- data/lib/active_record/attribute_methods/serialization.rb +150 -31
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -4
- data/lib/active_record/attribute_methods/write.rb +6 -6
- data/lib/active_record/attribute_methods.rb +148 -26
- data/lib/active_record/attributes.rb +3 -3
- data/lib/active_record/autosave_association.rb +59 -10
- data/lib/active_record/base.rb +7 -2
- 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 -42
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +163 -88
- 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 +80 -50
- 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 +62 -23
- data/lib/active_record/connection_adapters/abstract/quoting.rb +51 -7
- 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 +155 -25
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +297 -127
- data/lib/active_record/connection_adapters/abstract/transaction.rb +287 -58
- data/lib/active_record/connection_adapters/abstract_adapter.rb +509 -103
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +254 -125
- 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 -14
- 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 +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +19 -13
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +151 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +106 -55
- 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/cidr.rb +6 -0
- 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 +2 -2
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +41 -8
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +3 -9
- 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 +365 -61
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +354 -193
- 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 +9 -5
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +7 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +28 -9
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +213 -85
- 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 +258 -0
- data/lib/active_record/connection_adapters.rb +3 -1
- data/lib/active_record/connection_handling.rb +72 -95
- data/lib/active_record/core.rb +181 -154
- data/lib/active_record/counter_cache.rb +52 -27
- data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -1
- data/lib/active_record/database_configurations/database_config.rb +9 -3
- data/lib/active_record/database_configurations/hash_config.rb +28 -14
- data/lib/active_record/database_configurations/url_config.rb +17 -11
- data/lib/active_record/database_configurations.rb +86 -33
- data/lib/active_record/delegated_type.rb +15 -10
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +3 -1
- 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 +12 -19
- data/lib/active_record/encryption/context.rb +10 -3
- data/lib/active_record/encryption/contexts.rb +5 -1
- data/lib/active_record/encryption/derived_secret_key_provider.rb +8 -2
- data/lib/active_record/encryption/encryptable_record.rb +42 -18
- data/lib/active_record/encryption/encrypted_attribute_type.rb +23 -8
- data/lib/active_record/encryption/extended_deterministic_queries.rb +66 -69
- 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_serializer.rb +2 -0
- data/lib/active_record/encryption/properties.rb +3 -3
- data/lib/active_record/encryption/scheme.rb +22 -21
- data/lib/active_record/encryption.rb +3 -0
- data/lib/active_record/enum.rb +112 -28
- data/lib/active_record/errors.rb +112 -18
- 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 +135 -71
- data/lib/active_record/future_result.rb +40 -5
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +30 -16
- data/lib/active_record/insert_all.rb +57 -10
- data/lib/active_record/integration.rb +8 -8
- data/lib/active_record/internal_metadata.rb +120 -30
- data/lib/active_record/locking/optimistic.rb +33 -19
- data/lib/active_record/locking/pessimistic.rb +5 -2
- data/lib/active_record/log_subscriber.rb +29 -12
- data/lib/active_record/marshalling.rb +59 -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 +9 -11
- data/lib/active_record/middleware/shard_selector.rb +3 -1
- data/lib/active_record/migration/command_recorder.rb +105 -7
- data/lib/active_record/migration/compatibility.rb +163 -58
- 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 +271 -114
- data/lib/active_record/model_schema.rb +69 -44
- data/lib/active_record/nested_attributes.rb +37 -8
- data/lib/active_record/normalization.rb +167 -0
- data/lib/active_record/persistence.rb +195 -42
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +4 -22
- 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 +15 -2
- data/lib/active_record/railtie.rb +107 -45
- data/lib/active_record/railties/controller_runtime.rb +14 -9
- data/lib/active_record/railties/databases.rake +144 -150
- 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 +232 -81
- 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 +10 -7
- 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 +408 -76
- data/lib/active_record/relation/spawn_methods.rb +18 -1
- data/lib/active_record/relation.rb +103 -37
- data/lib/active_record/result.rb +25 -9
- data/lib/active_record/runtime_registry.rb +24 -1
- data/lib/active_record/sanitization.rb +51 -11
- data/lib/active_record/schema.rb +2 -3
- data/lib/active_record/schema_dumper.rb +50 -7
- data/lib/active_record/schema_migration.rb +68 -33
- data/lib/active_record/scoping/default.rb +15 -5
- 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/signed_id.rb +7 -5
- data/lib/active_record/store.rb +9 -9
- 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 +152 -108
- data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
- data/lib/active_record/tasks/postgresql_database_tasks.rb +16 -13
- data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
- data/lib/active_record/test_fixtures.rb +114 -96
- data/lib/active_record/timestamp.rb +30 -16
- 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/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/numericality.rb +5 -4
- data/lib/active_record/validations/presence.rb +5 -28
- data/lib/active_record/validations/uniqueness.rb +47 -2
- data/lib/active_record/validations.rb +8 -4
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +130 -17
- 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/tree_manager.rb +5 -1
- data/lib/arel/visitors/mysql.rb +8 -1
- data/lib/arel/visitors/to_sql.rb +83 -18
- 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
|
@@ -319,8 +335,8 @@ module ActiveRecord
|
|
319
335
|
|
320
336
|
private
|
321
337
|
def init_internals
|
322
|
-
@association_cache = {}
|
323
338
|
super
|
339
|
+
@association_cache = {}
|
324
340
|
end
|
325
341
|
|
326
342
|
# Returns the specified association instance if it exists, +nil+ otherwise.
|
@@ -333,6 +349,8 @@ module ActiveRecord
|
|
333
349
|
@association_cache[name] = association
|
334
350
|
end
|
335
351
|
|
352
|
+
# = Active Record \Associations
|
353
|
+
#
|
336
354
|
# \Associations are a set of macro-like class methods for tying objects together through
|
337
355
|
# foreign keys. They express relationships like "Project has one Project Manager"
|
338
356
|
# or "Project belongs to a Portfolio". Each macro adds a number of methods to the
|
@@ -349,23 +367,42 @@ module ActiveRecord
|
|
349
367
|
#
|
350
368
|
# The project class now has the following methods (and more) to ease the traversal and
|
351
369
|
# manipulation of its relationships:
|
352
|
-
#
|
353
|
-
#
|
354
|
-
#
|
355
|
-
#
|
356
|
-
#
|
357
|
-
#
|
358
|
-
#
|
370
|
+
#
|
371
|
+
# project = Project.first
|
372
|
+
# project.portfolio
|
373
|
+
# project.portfolio = Portfolio.first
|
374
|
+
# project.reload_portfolio
|
375
|
+
#
|
376
|
+
# project.project_manager
|
377
|
+
# project.project_manager = ProjectManager.first
|
378
|
+
# project.reload_project_manager
|
379
|
+
#
|
380
|
+
# project.milestones.empty?
|
381
|
+
# project.milestones.size
|
382
|
+
# project.milestones
|
383
|
+
# project.milestones << Milestone.first
|
384
|
+
# project.milestones.delete(Milestone.first)
|
385
|
+
# project.milestones.destroy(Milestone.first)
|
386
|
+
# project.milestones.find(Milestone.first.id)
|
387
|
+
# project.milestones.build
|
388
|
+
# project.milestones.create
|
389
|
+
#
|
390
|
+
# project.categories.empty?
|
391
|
+
# project.categories.size
|
392
|
+
# project.categories
|
393
|
+
# project.categories << Category.first
|
394
|
+
# project.categories.delete(category1)
|
395
|
+
# project.categories.destroy(category1)
|
359
396
|
#
|
360
397
|
# === A word of warning
|
361
398
|
#
|
362
399
|
# Don't create associations that have the same name as {instance methods}[rdoc-ref:ActiveRecord::Core] of
|
363
|
-
#
|
364
|
-
# its model, using an association with the same name as one provided by
|
365
|
-
# 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.
|
366
403
|
#
|
367
404
|
# == Auto-generated methods
|
368
|
-
# See also Instance Public methods below for more details.
|
405
|
+
# See also "Instance Public methods" below ( from #belongs_to ) for more details.
|
369
406
|
#
|
370
407
|
# === Singular associations (one-to-one)
|
371
408
|
# | | belongs_to |
|
@@ -586,8 +623,11 @@ module ActiveRecord
|
|
586
623
|
# has_many :birthday_events, ->(user) { where(starts_on: user.birthday) }, class_name: 'Event'
|
587
624
|
# end
|
588
625
|
#
|
589
|
-
# Note: Joining
|
590
|
-
#
|
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).
|
591
631
|
#
|
592
632
|
# == Association callbacks
|
593
633
|
#
|
@@ -608,6 +648,7 @@ module ActiveRecord
|
|
608
648
|
# def log_after_remove(record)
|
609
649
|
# # ...
|
610
650
|
# end
|
651
|
+
# end
|
611
652
|
#
|
612
653
|
# It's possible to stack callbacks by passing them as an array. Example:
|
613
654
|
#
|
@@ -1009,7 +1050,7 @@ module ActiveRecord
|
|
1009
1050
|
# query per addressable type.
|
1010
1051
|
# For example, if all the addressables are either of class Person or Company, then a total
|
1011
1052
|
# of 3 queries will be executed. The list of addressable types to load is determined on
|
1012
|
-
# the back of the addresses loaded. This is not supported if Active Record has to
|
1053
|
+
# the back of the addresses loaded. This is not supported if Active Record has to fall back
|
1013
1054
|
# to the previous implementation of eager loading and will raise ActiveRecord::EagerLoadPolymorphicError.
|
1014
1055
|
# The reason is that the parent model's type is a column value so its corresponding table
|
1015
1056
|
# name cannot be put in the +FROM+/+JOIN+ clauses of that query.
|
@@ -1022,45 +1063,45 @@ module ActiveRecord
|
|
1022
1063
|
# Indexes are appended for any more successive uses of the table name.
|
1023
1064
|
#
|
1024
1065
|
# Post.joins(:comments)
|
1025
|
-
# #
|
1066
|
+
# # SELECT ... FROM posts INNER JOIN comments ON ...
|
1026
1067
|
# Post.joins(:special_comments) # STI
|
1027
|
-
# #
|
1068
|
+
# # SELECT ... FROM posts INNER JOIN comments ON ... AND comments.type = 'SpecialComment'
|
1028
1069
|
# Post.joins(:comments, :special_comments) # special_comments is the reflection name, posts is the parent table name
|
1029
|
-
# #
|
1070
|
+
# # SELECT ... FROM posts INNER JOIN comments ON ... INNER JOIN comments special_comments_posts
|
1030
1071
|
#
|
1031
1072
|
# Acts as tree example:
|
1032
1073
|
#
|
1033
1074
|
# TreeMixin.joins(:children)
|
1034
|
-
# #
|
1075
|
+
# # SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
|
1035
1076
|
# TreeMixin.joins(children: :parent)
|
1036
|
-
# #
|
1037
|
-
#
|
1077
|
+
# # SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
|
1078
|
+
# # INNER JOIN parents_mixins ...
|
1038
1079
|
# TreeMixin.joins(children: {parent: :children})
|
1039
|
-
# #
|
1040
|
-
#
|
1041
|
-
#
|
1080
|
+
# # SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
|
1081
|
+
# # INNER JOIN parents_mixins ...
|
1082
|
+
# # INNER JOIN mixins childrens_mixins_2
|
1042
1083
|
#
|
1043
1084
|
# Has and Belongs to Many join tables use the same idea, but add a <tt>_join</tt> suffix:
|
1044
1085
|
#
|
1045
1086
|
# Post.joins(:categories)
|
1046
|
-
# #
|
1087
|
+
# # SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
|
1047
1088
|
# Post.joins(categories: :posts)
|
1048
|
-
# #
|
1049
|
-
#
|
1089
|
+
# # SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
|
1090
|
+
# # INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
|
1050
1091
|
# Post.joins(categories: {posts: :categories})
|
1051
|
-
# #
|
1052
|
-
#
|
1053
|
-
#
|
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
|
1054
1095
|
#
|
1055
1096
|
# If you wish to specify your own custom joins using ActiveRecord::QueryMethods#joins method, those table
|
1056
1097
|
# names will take precedence over the eager associations:
|
1057
1098
|
#
|
1058
1099
|
# Post.joins(:comments).joins("inner join comments ...")
|
1059
|
-
# #
|
1100
|
+
# # SELECT ... FROM posts INNER JOIN comments_posts ON ... INNER JOIN comments ...
|
1060
1101
|
# Post.joins(:comments, :special_comments).joins("inner join comments ...")
|
1061
|
-
# #
|
1062
|
-
#
|
1063
|
-
#
|
1102
|
+
# # SELECT ... FROM posts INNER JOIN comments comments_posts ON ...
|
1103
|
+
# # INNER JOIN comments special_comments_posts ...
|
1104
|
+
# # INNER JOIN comments ...
|
1064
1105
|
#
|
1065
1106
|
# Table aliases are automatically truncated according to the maximum length of table identifiers
|
1066
1107
|
# according to the specific database.
|
@@ -1141,7 +1182,8 @@ module ActiveRecord
|
|
1141
1182
|
# belongs_to :dungeon, inverse_of: :evil_wizard
|
1142
1183
|
# end
|
1143
1184
|
#
|
1144
|
-
# 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].
|
1145
1187
|
#
|
1146
1188
|
# == Deleting from associations
|
1147
1189
|
#
|
@@ -1163,7 +1205,7 @@ module ActiveRecord
|
|
1163
1205
|
# specific association types. When no option is given, the behavior is to do nothing
|
1164
1206
|
# with the associated records when destroying a record.
|
1165
1207
|
#
|
1166
|
-
# Note that <tt>:dependent</tt> is implemented using Rails' callback
|
1208
|
+
# Note that <tt>:dependent</tt> is implemented using \Rails' callback
|
1167
1209
|
# system, which works by processing callbacks in order. Therefore, other
|
1168
1210
|
# callbacks declared either before or after the <tt>:dependent</tt> option
|
1169
1211
|
# can affect what it does.
|
@@ -1234,15 +1276,15 @@ module ActiveRecord
|
|
1234
1276
|
# +collection+ is a placeholder for the symbol passed as the +name+ argument, so
|
1235
1277
|
# <tt>has_many :clients</tt> would add among others <tt>clients.empty?</tt>.
|
1236
1278
|
#
|
1237
|
-
# [collection]
|
1279
|
+
# [<tt>collection</tt>]
|
1238
1280
|
# Returns a Relation of all the associated objects.
|
1239
1281
|
# An empty Relation is returned if none are found.
|
1240
|
-
# [collection<<(object, ...)]
|
1282
|
+
# [<tt>collection<<(object, ...)</tt>]
|
1241
1283
|
# Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
|
1242
1284
|
# Note that this operation instantly fires update SQL without waiting for the save or update call on the
|
1243
1285
|
# parent object, unless the parent object is a new record.
|
1244
1286
|
# This will also run validations and callbacks of associated object(s).
|
1245
|
-
# [collection.delete(object, ...)]
|
1287
|
+
# [<tt>collection.delete(object, ...)</tt>]
|
1246
1288
|
# Removes one or more objects from the collection by setting their foreign keys to +NULL+.
|
1247
1289
|
# Objects will be in addition destroyed if they're associated with <tt>dependent: :destroy</tt>,
|
1248
1290
|
# and deleted if they're associated with <tt>dependent: :delete_all</tt>.
|
@@ -1250,75 +1292,84 @@ module ActiveRecord
|
|
1250
1292
|
# If the <tt>:through</tt> option is used, then the join records are deleted (rather than
|
1251
1293
|
# nullified) by default, but you can specify <tt>dependent: :destroy</tt> or
|
1252
1294
|
# <tt>dependent: :nullify</tt> to override this.
|
1253
|
-
# [collection.destroy(object, ...)]
|
1295
|
+
# [<tt>collection.destroy(object, ...)</tt>]
|
1254
1296
|
# Removes one or more objects from the collection by running <tt>destroy</tt> on
|
1255
1297
|
# each record, regardless of any dependent option, ensuring callbacks are run.
|
1256
1298
|
#
|
1257
1299
|
# If the <tt>:through</tt> option is used, then the join records are destroyed
|
1258
1300
|
# instead, not the objects themselves.
|
1259
|
-
# [collection=objects]
|
1301
|
+
# [<tt>collection=objects</tt>]
|
1260
1302
|
# Replaces the collections content by deleting and adding objects as appropriate. If the <tt>:through</tt>
|
1261
1303
|
# option is true callbacks in the join models are triggered except destroy callbacks, since deletion is
|
1262
1304
|
# direct by default. You can specify <tt>dependent: :destroy</tt> or
|
1263
1305
|
# <tt>dependent: :nullify</tt> to override this.
|
1264
|
-
# [collection_singular_ids]
|
1306
|
+
# [<tt>collection_singular_ids</tt>]
|
1265
1307
|
# Returns an array of the associated objects' ids
|
1266
|
-
# [collection_singular_ids=ids]
|
1308
|
+
# [<tt>collection_singular_ids=ids</tt>]
|
1267
1309
|
# Replace the collection with the objects identified by the primary keys in +ids+. This
|
1268
1310
|
# method loads the models and calls <tt>collection=</tt>. See above.
|
1269
|
-
# [collection.clear]
|
1311
|
+
# [<tt>collection.clear</tt>]
|
1270
1312
|
# Removes every object from the collection. This destroys the associated objects if they
|
1271
1313
|
# are associated with <tt>dependent: :destroy</tt>, deletes them directly from the
|
1272
1314
|
# database if <tt>dependent: :delete_all</tt>, otherwise sets their foreign keys to +NULL+.
|
1273
1315
|
# If the <tt>:through</tt> option is true no destroy callbacks are invoked on the join models.
|
1274
1316
|
# Join models are directly deleted.
|
1275
|
-
# [collection.empty
|
1317
|
+
# [<tt>collection.empty?</tt>]
|
1276
1318
|
# Returns +true+ if there are no associated objects.
|
1277
|
-
# [collection.size]
|
1319
|
+
# [<tt>collection.size</tt>]
|
1278
1320
|
# Returns the number of associated objects.
|
1279
|
-
# [collection.find(...)]
|
1321
|
+
# [<tt>collection.find(...)</tt>]
|
1280
1322
|
# Finds an associated object according to the same rules as ActiveRecord::FinderMethods#find.
|
1281
|
-
# [collection.exists?(...)]
|
1323
|
+
# [<tt>collection.exists?(...)</tt>]
|
1282
1324
|
# Checks whether an associated object with the given conditions exists.
|
1283
1325
|
# Uses the same rules as ActiveRecord::FinderMethods#exists?.
|
1284
|
-
# [collection.build(attributes = {}, ...)]
|
1326
|
+
# [<tt>collection.build(attributes = {}, ...)</tt>]
|
1285
1327
|
# Returns one or more new objects of the collection type that have been instantiated
|
1286
1328
|
# with +attributes+ and linked to this object through a foreign key, but have not yet
|
1287
1329
|
# been saved.
|
1288
|
-
# [collection.create(attributes = {})]
|
1330
|
+
# [<tt>collection.create(attributes = {})</tt>]
|
1289
1331
|
# Returns a new object of the collection type that has been instantiated
|
1290
1332
|
# with +attributes+, linked to this object through a foreign key, and that has already
|
1291
1333
|
# been saved (if it passed the validation). *Note*: This only works if the base model
|
1292
1334
|
# already exists in the DB, not if it is a new (unsaved) record!
|
1293
|
-
# [collection.create!(attributes = {})]
|
1335
|
+
# [<tt>collection.create!(attributes = {})</tt>]
|
1294
1336
|
# Does the same as <tt>collection.create</tt>, but raises ActiveRecord::RecordInvalid
|
1295
1337
|
# if the record is invalid.
|
1296
|
-
# [collection.reload]
|
1338
|
+
# [<tt>collection.reload</tt>]
|
1297
1339
|
# Returns a Relation of all of the associated objects, forcing a database read.
|
1298
1340
|
# An empty Relation is returned if none are found.
|
1299
1341
|
#
|
1300
|
-
#
|
1301
|
-
#
|
1302
|
-
#
|
1303
|
-
#
|
1304
|
-
#
|
1305
|
-
#
|
1306
|
-
#
|
1307
|
-
#
|
1308
|
-
#
|
1309
|
-
#
|
1310
|
-
#
|
1311
|
-
#
|
1312
|
-
#
|
1313
|
-
#
|
1314
|
-
#
|
1315
|
-
#
|
1316
|
-
#
|
1317
|
-
#
|
1318
|
-
#
|
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
|
+
#
|
1319
1370
|
# The declaration can also include an +options+ hash to specialize the behavior of the association.
|
1320
1371
|
#
|
1321
|
-
#
|
1372
|
+
# ==== Scopes
|
1322
1373
|
#
|
1323
1374
|
# You can pass a second argument +scope+ as a callable (i.e. proc or
|
1324
1375
|
# lambda) to retrieve a specific set of records or customize the generated
|
@@ -1329,7 +1380,7 @@ module ActiveRecord
|
|
1329
1380
|
# has_many :employees, -> { joins(:address) }
|
1330
1381
|
# has_many :posts, ->(blog) { where("max_post_length > ?", blog.max_post_length) }
|
1331
1382
|
#
|
1332
|
-
#
|
1383
|
+
# ==== Extensions
|
1333
1384
|
#
|
1334
1385
|
# The +extension+ argument allows you to pass a block into a has_many
|
1335
1386
|
# association. This is useful for adding new finders, creators, and other
|
@@ -1343,31 +1394,31 @@ module ActiveRecord
|
|
1343
1394
|
# end
|
1344
1395
|
# end
|
1345
1396
|
#
|
1346
|
-
#
|
1347
|
-
# [
|
1397
|
+
# ==== Options
|
1398
|
+
# [+:class_name+]
|
1348
1399
|
# Specify the class name of the association. Use it only if that name can't be inferred
|
1349
1400
|
# from the association name. So <tt>has_many :products</tt> will by default be linked
|
1350
1401
|
# to the +Product+ class, but if the real class name is +SpecialProduct+, you'll have to
|
1351
1402
|
# specify it with this option.
|
1352
|
-
# [
|
1403
|
+
# [+:foreign_key+]
|
1353
1404
|
# Specify the foreign key used for the association. By default this is guessed to be the name
|
1354
1405
|
# of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_many
|
1355
1406
|
# association will use "person_id" as the default <tt>:foreign_key</tt>.
|
1356
1407
|
#
|
1357
|
-
#
|
1358
|
-
# a good idea to set the <tt>:inverse_of</tt> option.
|
1359
|
-
# [
|
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+]
|
1360
1411
|
# Specify the column used to store the associated object's type, if this is a polymorphic
|
1361
1412
|
# association. By default this is guessed to be the name of the polymorphic association
|
1362
1413
|
# specified on "as" option with a "_type" suffix. So a class that defines a
|
1363
1414
|
# <tt>has_many :tags, as: :taggable</tt> association will use "taggable_type" as the
|
1364
1415
|
# default <tt>:foreign_type</tt>.
|
1365
|
-
# [
|
1416
|
+
# [+:primary_key+]
|
1366
1417
|
# Specify the name of the column to use as the primary key for the association. By default this is +id+.
|
1367
|
-
# [
|
1418
|
+
# [+:dependent+]
|
1368
1419
|
# Controls what happens to the associated objects when
|
1369
1420
|
# their owner is destroyed. Note that these are implemented as
|
1370
|
-
# callbacks, and Rails executes callbacks in order. Therefore, other
|
1421
|
+
# callbacks, and \Rails executes callbacks in order. Therefore, other
|
1371
1422
|
# similar callbacks may affect the <tt>:dependent</tt> behavior, and the
|
1372
1423
|
# <tt>:dependent</tt> behavior may affect other callbacks.
|
1373
1424
|
#
|
@@ -1379,7 +1430,7 @@ module ActiveRecord
|
|
1379
1430
|
# * <tt>:delete_all</tt> causes all the associated objects to be deleted directly from the database (so callbacks will not be executed).
|
1380
1431
|
# * <tt>:nullify</tt> causes the foreign keys to be set to +NULL+. Polymorphic type will also be nullified
|
1381
1432
|
# on polymorphic associations. Callbacks are not executed.
|
1382
|
-
# * <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.
|
1383
1434
|
# * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there are any associated objects.
|
1384
1435
|
#
|
1385
1436
|
# If using with the <tt>:through</tt> option, the association on the join model must be
|
@@ -1391,12 +1442,12 @@ module ActiveRecord
|
|
1391
1442
|
# <tt>has_many :comments, -> { where published: true }, dependent: :destroy</tt> and <tt>destroy</tt> is
|
1392
1443
|
# called on a post, only published comments are destroyed. This means that any unpublished comments in the
|
1393
1444
|
# database would still contain a foreign key pointing to the now deleted post.
|
1394
|
-
# [
|
1445
|
+
# [+:counter_cache+]
|
1395
1446
|
# This option can be used to configure a custom named <tt>:counter_cache.</tt> You only need this option,
|
1396
1447
|
# when you customized the name of your <tt>:counter_cache</tt> on the #belongs_to association.
|
1397
|
-
# [
|
1448
|
+
# [+:as+]
|
1398
1449
|
# Specifies a polymorphic interface (See #belongs_to).
|
1399
|
-
# [
|
1450
|
+
# [+:through+]
|
1400
1451
|
# Specifies an association through which to perform the query. This can be any other type
|
1401
1452
|
# of association, including other <tt>:through</tt> associations. Options for <tt>:class_name</tt>,
|
1402
1453
|
# <tt>:primary_key</tt> and <tt>:foreign_key</tt> are ignored, as the association uses the
|
@@ -1411,24 +1462,24 @@ module ActiveRecord
|
|
1411
1462
|
# a good idea to set the <tt>:inverse_of</tt> option on the source association on the
|
1412
1463
|
# join model. This allows associated records to be built which will automatically create
|
1413
1464
|
# the appropriate join model records when they are saved. (See the 'Association Join Models'
|
1414
|
-
#
|
1415
|
-
# [
|
1465
|
+
# and 'Setting Inverses' sections above.)
|
1466
|
+
# [+:disable_joins+]
|
1416
1467
|
# Specifies whether joins should be skipped for an association. If set to true, two or more queries
|
1417
1468
|
# will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory
|
1418
1469
|
# due to database limitations. This option is only applicable on <tt>has_many :through</tt> associations as
|
1419
1470
|
# +has_many+ alone do not perform a join.
|
1420
|
-
# [
|
1471
|
+
# [+:source+]
|
1421
1472
|
# Specifies the source association name used by #has_many <tt>:through</tt> queries.
|
1422
1473
|
# Only use it if the name cannot be inferred from the association.
|
1423
1474
|
# <tt>has_many :subscribers, through: :subscriptions</tt> will look for either <tt>:subscribers</tt> or
|
1424
1475
|
# <tt>:subscriber</tt> on Subscription, unless a <tt>:source</tt> is given.
|
1425
|
-
# [
|
1476
|
+
# [+:source_type+]
|
1426
1477
|
# Specifies type of the source association used by #has_many <tt>:through</tt> queries where the source
|
1427
1478
|
# association is a polymorphic #belongs_to.
|
1428
|
-
# [
|
1479
|
+
# [+:validate+]
|
1429
1480
|
# When set to +true+, validates new objects added to association when saving the parent object. +true+ by default.
|
1430
1481
|
# If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
|
1431
|
-
# [
|
1482
|
+
# [+:autosave+]
|
1432
1483
|
# If true, always save the associated objects or destroy them if marked for destruction,
|
1433
1484
|
# when saving the parent object. If false, never save or destroy the associated objects.
|
1434
1485
|
# By default, only save associated objects that are new records. This option is implemented as a
|
@@ -1437,20 +1488,29 @@ module ActiveRecord
|
|
1437
1488
|
#
|
1438
1489
|
# Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
|
1439
1490
|
# <tt>:autosave</tt> to <tt>true</tt>.
|
1440
|
-
# [
|
1491
|
+
# [+:inverse_of+]
|
1441
1492
|
# Specifies the name of the #belongs_to association on the associated object
|
1442
1493
|
# that is the inverse of this #has_many association.
|
1443
1494
|
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
|
1444
|
-
# [
|
1495
|
+
# [+:extend+]
|
1445
1496
|
# Specifies a module or array of modules that will be extended into the association object returned.
|
1446
1497
|
# Useful for defining methods on associations, especially when they should be shared between multiple
|
1447
1498
|
# association objects.
|
1448
|
-
# [
|
1499
|
+
# [+:strict_loading+]
|
1449
1500
|
# When set to +true+, enforces strict loading every time the associated record is loaded through this
|
1450
1501
|
# association.
|
1451
|
-
# [
|
1502
|
+
# [+:ensuring_owner_was+]
|
1452
1503
|
# Specifies an instance method to be called on the owner. The method must return true in order for the
|
1453
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.
|
1509
|
+
# [+:index_errors+]
|
1510
|
+
# Enables differentiation of multiple validation errors from the association records, by including
|
1511
|
+
# an index in the error attribute name, e.g. +roles[2].level+.
|
1512
|
+
# The index is based on association order, i.e. database order, with yet to be
|
1513
|
+
# persisted new records placed at the end.
|
1454
1514
|
#
|
1455
1515
|
# Option examples:
|
1456
1516
|
# has_many :comments, -> { order("posted_on") }
|
@@ -1463,6 +1523,8 @@ module ActiveRecord
|
|
1463
1523
|
# has_many :subscribers, through: :subscriptions, source: :user
|
1464
1524
|
# has_many :subscribers, through: :subscriptions, disable_joins: true
|
1465
1525
|
# has_many :comments, strict_loading: true
|
1526
|
+
# has_many :comments, query_constraints: [:blog_id, :post_id]
|
1527
|
+
# has_many :comments, index_errors: true
|
1466
1528
|
def has_many(name, scope = nil, **options, &extension)
|
1467
1529
|
reflection = Builder::HasMany.build(self, name, scope, options, &extension)
|
1468
1530
|
Reflection.add_reflection self, name, reflection
|
@@ -1478,37 +1540,48 @@ module ActiveRecord
|
|
1478
1540
|
# +association+ is a placeholder for the symbol passed as the +name+ argument, so
|
1479
1541
|
# <tt>has_one :manager</tt> would add among others <tt>manager.nil?</tt>.
|
1480
1542
|
#
|
1481
|
-
# [association]
|
1543
|
+
# [<tt>association</tt>]
|
1482
1544
|
# Returns the associated object. +nil+ is returned if none is found.
|
1483
|
-
# [association=(associate)]
|
1545
|
+
# [<tt>association=(associate)</tt>]
|
1484
1546
|
# Assigns the associate object, extracts the primary key, sets it as the foreign key,
|
1485
1547
|
# and saves the associate object. To avoid database inconsistencies, permanently deletes an existing
|
1486
1548
|
# associated object when assigning a new one, even if the new one isn't saved to database.
|
1487
|
-
# [build_association(attributes = {})]
|
1549
|
+
# [<tt>build_association(attributes = {})</tt>]
|
1488
1550
|
# Returns a new object of the associated type that has been instantiated
|
1489
1551
|
# with +attributes+ and linked to this object through a foreign key, but has not
|
1490
1552
|
# yet been saved.
|
1491
|
-
# [create_association(attributes = {})]
|
1553
|
+
# [<tt>create_association(attributes = {})</tt>]
|
1492
1554
|
# Returns a new object of the associated type that has been instantiated
|
1493
1555
|
# with +attributes+, linked to this object through a foreign key, and that
|
1494
1556
|
# has already been saved (if it passed the validation).
|
1495
|
-
# [create_association!(attributes = {})]
|
1557
|
+
# [<tt>create_association!(attributes = {})</tt>]
|
1496
1558
|
# Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
|
1497
1559
|
# if the record is invalid.
|
1498
|
-
# [reload_association]
|
1560
|
+
# [<tt>reload_association</tt>]
|
1499
1561
|
# Returns the associated object, forcing a database read.
|
1562
|
+
# [<tt>reset_association</tt>]
|
1563
|
+
# Unloads the associated object. The next access will query it from the database.
|
1564
|
+
#
|
1565
|
+
# ==== Example
|
1566
|
+
#
|
1567
|
+
# class Account < ActiveRecord::Base
|
1568
|
+
# has_one :beneficiary
|
1569
|
+
# end
|
1570
|
+
#
|
1571
|
+
# Declaring <tt>has_one :beneficiary</tt> adds the following methods (and more):
|
1500
1572
|
#
|
1501
|
-
#
|
1573
|
+
# account = Account.find(5)
|
1574
|
+
# beneficiary = Beneficiary.find(8)
|
1502
1575
|
#
|
1503
|
-
#
|
1504
|
-
#
|
1505
|
-
#
|
1506
|
-
#
|
1507
|
-
#
|
1508
|
-
#
|
1509
|
-
#
|
1576
|
+
# account.beneficiary # similar to Beneficiary.find_by(account_id: 5)
|
1577
|
+
# account.beneficiary = beneficiary # similar to beneficiary.update(account_id: 5)
|
1578
|
+
# account.build_beneficiary # similar to Beneficiary.new(account_id: 5)
|
1579
|
+
# account.create_beneficiary # similar to Beneficiary.create(account_id: 5)
|
1580
|
+
# account.create_beneficiary! # similar to Beneficiary.create!(account_id: 5)
|
1581
|
+
# account.reload_beneficiary
|
1582
|
+
# account.reset_beneficiary
|
1510
1583
|
#
|
1511
|
-
#
|
1584
|
+
# ==== Scopes
|
1512
1585
|
#
|
1513
1586
|
# You can pass a second argument +scope+ as a callable (i.e. proc or
|
1514
1587
|
# lambda) to retrieve a specific record or customize the generated query
|
@@ -1519,16 +1592,16 @@ module ActiveRecord
|
|
1519
1592
|
# has_one :employer, -> { joins(:company) }
|
1520
1593
|
# has_one :latest_post, ->(blog) { where("created_at > ?", blog.enabled_at) }
|
1521
1594
|
#
|
1522
|
-
#
|
1595
|
+
# ==== Options
|
1523
1596
|
#
|
1524
1597
|
# The declaration can also include an +options+ hash to specialize the behavior of the association.
|
1525
1598
|
#
|
1526
1599
|
# Options are:
|
1527
|
-
# [
|
1600
|
+
# [+:class_name+]
|
1528
1601
|
# Specify the class name of the association. Use it only if that name can't be inferred
|
1529
1602
|
# from the association name. So <tt>has_one :manager</tt> will by default be linked to the Manager class, but
|
1530
1603
|
# if the real class name is Person, you'll have to specify it with this option.
|
1531
|
-
# [
|
1604
|
+
# [+:dependent+]
|
1532
1605
|
# Controls what happens to the associated object when
|
1533
1606
|
# its owner is destroyed:
|
1534
1607
|
#
|
@@ -1540,28 +1613,28 @@ module ActiveRecord
|
|
1540
1613
|
# * <tt>:delete</tt> causes the associated object to be deleted directly from the database (so callbacks will not execute)
|
1541
1614
|
# * <tt>:nullify</tt> causes the foreign key to be set to +NULL+. Polymorphic type column is also nullified
|
1542
1615
|
# on polymorphic associations. Callbacks are not executed.
|
1543
|
-
# * <tt>:restrict_with_exception</tt> causes an
|
1616
|
+
# * <tt>:restrict_with_exception</tt> causes an ActiveRecord::DeleteRestrictionError exception to be raised if there is an associated record
|
1544
1617
|
# * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there is an associated object
|
1545
1618
|
#
|
1546
1619
|
# Note that <tt>:dependent</tt> option is ignored when using <tt>:through</tt> option.
|
1547
|
-
# [
|
1620
|
+
# [+:foreign_key+]
|
1548
1621
|
# Specify the foreign key used for the association. By default this is guessed to be the name
|
1549
1622
|
# of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_one association
|
1550
1623
|
# will use "person_id" as the default <tt>:foreign_key</tt>.
|
1551
1624
|
#
|
1552
|
-
#
|
1553
|
-
# a good idea to set the <tt>:inverse_of</tt> option.
|
1554
|
-
# [
|
1625
|
+
# Setting the <tt>:foreign_key</tt> option prevents automatic detection of the association's
|
1626
|
+
# inverse, so it is generally a good idea to set the <tt>:inverse_of</tt> option as well.
|
1627
|
+
# [+:foreign_type+]
|
1555
1628
|
# Specify the column used to store the associated object's type, if this is a polymorphic
|
1556
1629
|
# association. By default this is guessed to be the name of the polymorphic association
|
1557
1630
|
# specified on "as" option with a "_type" suffix. So a class that defines a
|
1558
1631
|
# <tt>has_one :tag, as: :taggable</tt> association will use "taggable_type" as the
|
1559
1632
|
# default <tt>:foreign_type</tt>.
|
1560
|
-
# [
|
1633
|
+
# [+:primary_key+]
|
1561
1634
|
# Specify the method that returns the primary key used for the association. By default this is +id+.
|
1562
|
-
# [
|
1635
|
+
# [+:as+]
|
1563
1636
|
# Specifies a polymorphic interface (See #belongs_to).
|
1564
|
-
# [
|
1637
|
+
# [+:through+]
|
1565
1638
|
# Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt>,
|
1566
1639
|
# <tt>:primary_key</tt>, and <tt>:foreign_key</tt> are ignored, as the association uses the
|
1567
1640
|
# source reflection. You can only use a <tt>:through</tt> query through a #has_one
|
@@ -1576,43 +1649,53 @@ module ActiveRecord
|
|
1576
1649
|
# a good idea to set the <tt>:inverse_of</tt> option on the source association on the
|
1577
1650
|
# join model. This allows associated records to be built which will automatically create
|
1578
1651
|
# the appropriate join model records when they are saved. (See the 'Association Join Models'
|
1579
|
-
#
|
1580
|
-
# [
|
1652
|
+
# and 'Setting Inverses' sections above.)
|
1653
|
+
# [+:disable_joins+]
|
1581
1654
|
# Specifies whether joins should be skipped for an association. If set to true, two or more queries
|
1582
1655
|
# will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory
|
1583
1656
|
# due to database limitations. This option is only applicable on <tt>has_one :through</tt> associations as
|
1584
1657
|
# +has_one+ alone does not perform a join.
|
1585
|
-
# [
|
1658
|
+
# [+:source+]
|
1586
1659
|
# Specifies the source association name used by #has_one <tt>:through</tt> queries.
|
1587
1660
|
# Only use it if the name cannot be inferred from the association.
|
1588
1661
|
# <tt>has_one :favorite, through: :favorites</tt> will look for a
|
1589
1662
|
# <tt>:favorite</tt> on Favorite, unless a <tt>:source</tt> is given.
|
1590
|
-
# [
|
1663
|
+
# [+:source_type+]
|
1591
1664
|
# Specifies type of the source association used by #has_one <tt>:through</tt> queries where the source
|
1592
1665
|
# association is a polymorphic #belongs_to.
|
1593
|
-
# [
|
1666
|
+
# [+:validate+]
|
1594
1667
|
# When set to +true+, validates new objects added to association when saving the parent object. +false+ by default.
|
1595
1668
|
# If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
|
1596
|
-
# [
|
1669
|
+
# [+:autosave+]
|
1597
1670
|
# If true, always save the associated object or destroy it if marked for destruction,
|
1598
1671
|
# when saving the parent object. If false, never save or destroy the associated object.
|
1599
1672
|
# By default, only save the associated object if it's a new record.
|
1600
1673
|
#
|
1601
1674
|
# Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
|
1602
1675
|
# <tt>:autosave</tt> to <tt>true</tt>.
|
1603
|
-
# [
|
1676
|
+
# [+:touch+]
|
1677
|
+
# If true, the associated object will be touched (the +updated_at+ / +updated_on+ attributes set to current time)
|
1678
|
+
# when this record is either saved or destroyed. If you specify a symbol, that attribute
|
1679
|
+
# will be updated with the current time in addition to the +updated_at+ / +updated_on+ attribute.
|
1680
|
+
# Please note that no validation will be performed when touching, and only the +after_touch+,
|
1681
|
+
# +after_commit+, and +after_rollback+ callbacks will be executed.
|
1682
|
+
# [+:inverse_of+]
|
1604
1683
|
# Specifies the name of the #belongs_to association on the associated object
|
1605
1684
|
# that is the inverse of this #has_one association.
|
1606
1685
|
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
|
1607
|
-
# [
|
1686
|
+
# [+:required+]
|
1608
1687
|
# When set to +true+, the association will also have its presence validated.
|
1609
1688
|
# This will validate the association itself, not the id. You can use
|
1610
1689
|
# +:inverse_of+ to avoid an extra query during validation.
|
1611
|
-
# [
|
1690
|
+
# [+:strict_loading+]
|
1612
1691
|
# Enforces strict loading every time the associated record is loaded through this association.
|
1613
|
-
# [
|
1692
|
+
# [+:ensuring_owner_was+]
|
1614
1693
|
# Specifies an instance method to be called on the owner. The method must return true in order for the
|
1615
1694
|
# associated records to be deleted in a background job.
|
1695
|
+
# [+:query_constraints+]
|
1696
|
+
# Serves as a composite foreign key. Defines the list of columns to be used to query the associated object.
|
1697
|
+
# This is an optional option. By default Rails will attempt to derive the value automatically.
|
1698
|
+
# When the value is set the Array size must match associated model's primary key or +query_constraints+ size.
|
1616
1699
|
#
|
1617
1700
|
# Option examples:
|
1618
1701
|
# has_one :credit_card, dependent: :destroy # destroys the associated credit card
|
@@ -1627,6 +1710,7 @@ module ActiveRecord
|
|
1627
1710
|
# has_one :primary_address, -> { where(primary: true) }, through: :addressables, source: :addressable
|
1628
1711
|
# has_one :credit_card, required: true
|
1629
1712
|
# has_one :credit_card, strict_loading: true
|
1713
|
+
# has_one :employment_record_book, query_constraints: [:organization_id, :employee_id]
|
1630
1714
|
def has_one(name, scope = nil, **options)
|
1631
1715
|
reflection = Builder::HasOne.build(self, name, scope, options)
|
1632
1716
|
Reflection.add_reflection self, name, reflection
|
@@ -1643,42 +1727,52 @@ module ActiveRecord
|
|
1643
1727
|
# +association+ is a placeholder for the symbol passed as the +name+ argument, so
|
1644
1728
|
# <tt>belongs_to :author</tt> would add among others <tt>author.nil?</tt>.
|
1645
1729
|
#
|
1646
|
-
# [association]
|
1730
|
+
# [<tt>association</tt>]
|
1647
1731
|
# Returns the associated object. +nil+ is returned if none is found.
|
1648
|
-
# [association=(associate)]
|
1732
|
+
# [<tt>association=(associate)</tt>]
|
1649
1733
|
# Assigns the associate object, extracts the primary key, and sets it as the foreign key.
|
1650
1734
|
# No modification or deletion of existing records takes place.
|
1651
|
-
# [build_association(attributes = {})]
|
1735
|
+
# [<tt>build_association(attributes = {})</tt>]
|
1652
1736
|
# Returns a new object of the associated type that has been instantiated
|
1653
1737
|
# with +attributes+ and linked to this object through a foreign key, but has not yet been saved.
|
1654
|
-
# [create_association(attributes = {})]
|
1738
|
+
# [<tt>create_association(attributes = {})</tt>]
|
1655
1739
|
# Returns a new object of the associated type that has been instantiated
|
1656
1740
|
# with +attributes+, linked to this object through a foreign key, and that
|
1657
1741
|
# has already been saved (if it passed the validation).
|
1658
|
-
# [create_association!(attributes = {})]
|
1742
|
+
# [<tt>create_association!(attributes = {})</tt>]
|
1659
1743
|
# Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
|
1660
1744
|
# if the record is invalid.
|
1661
|
-
# [reload_association]
|
1745
|
+
# [<tt>reload_association</tt>]
|
1662
1746
|
# Returns the associated object, forcing a database read.
|
1663
|
-
# [
|
1747
|
+
# [<tt>reset_association</tt>]
|
1748
|
+
# Unloads the associated object. The next access will query it from the database.
|
1749
|
+
# [<tt>association_changed?</tt>]
|
1664
1750
|
# Returns true if a new associate object has been assigned and the next save will update the foreign key.
|
1665
|
-
# [association_previously_changed
|
1751
|
+
# [<tt>association_previously_changed?</tt>]
|
1666
1752
|
# Returns true if the previous save updated the association to reference a new associate object.
|
1667
1753
|
#
|
1668
|
-
#
|
1669
|
-
#
|
1670
|
-
#
|
1671
|
-
#
|
1672
|
-
#
|
1673
|
-
#
|
1674
|
-
#
|
1675
|
-
# * <tt>Post#create_author!</tt> (similar to <tt>post.author = Author.new; post.author.save!; post.author</tt>)
|
1676
|
-
# * <tt>Post#reload_author</tt>
|
1677
|
-
# * <tt>Post#author_changed?</tt>
|
1678
|
-
# * <tt>Post#author_previously_changed?</tt>
|
1679
|
-
# The declaration can also include an +options+ hash to specialize the behavior of the association.
|
1754
|
+
# ==== Example
|
1755
|
+
#
|
1756
|
+
# class Post < ActiveRecord::Base
|
1757
|
+
# belongs_to :author
|
1758
|
+
# end
|
1759
|
+
#
|
1760
|
+
# Declaring <tt>belongs_to :author</tt> adds the following methods (and more):
|
1680
1761
|
#
|
1681
|
-
#
|
1762
|
+
# post = Post.find(7)
|
1763
|
+
# author = Author.find(19)
|
1764
|
+
#
|
1765
|
+
# post.author # similar to Author.find(post.author_id)
|
1766
|
+
# post.author = author # similar to post.author_id = author.id
|
1767
|
+
# post.build_author # similar to post.author = Author.new
|
1768
|
+
# post.create_author # similar to post.author = Author.new; post.author.save; post.author
|
1769
|
+
# post.create_author! # similar to post.author = Author.new; post.author.save!; post.author
|
1770
|
+
# post.reload_author
|
1771
|
+
# post.reset_author
|
1772
|
+
# post.author_changed?
|
1773
|
+
# post.author_previously_changed?
|
1774
|
+
#
|
1775
|
+
# ==== Scopes
|
1682
1776
|
#
|
1683
1777
|
# You can pass a second argument +scope+ as a callable (i.e. proc or
|
1684
1778
|
# lambda) to retrieve a specific record or customize the generated query
|
@@ -1689,37 +1783,39 @@ module ActiveRecord
|
|
1689
1783
|
# belongs_to :user, -> { joins(:friends) }
|
1690
1784
|
# belongs_to :level, ->(game) { where("game_level > ?", game.current_level) }
|
1691
1785
|
#
|
1692
|
-
#
|
1786
|
+
# ==== Options
|
1693
1787
|
#
|
1694
|
-
#
|
1788
|
+
# The declaration can also include an +options+ hash to specialize the behavior of the association.
|
1789
|
+
#
|
1790
|
+
# [+:class_name+]
|
1695
1791
|
# Specify the class name of the association. Use it only if that name can't be inferred
|
1696
1792
|
# from the association name. So <tt>belongs_to :author</tt> will by default be linked to the Author class, but
|
1697
1793
|
# if the real class name is Person, you'll have to specify it with this option.
|
1698
|
-
# [
|
1794
|
+
# [+:foreign_key+]
|
1699
1795
|
# Specify the foreign key used for the association. By default this is guessed to be the name
|
1700
1796
|
# of the association with an "_id" suffix. So a class that defines a <tt>belongs_to :person</tt>
|
1701
1797
|
# association will use "person_id" as the default <tt>:foreign_key</tt>. Similarly,
|
1702
1798
|
# <tt>belongs_to :favorite_person, class_name: "Person"</tt> will use a foreign key
|
1703
1799
|
# of "favorite_person_id".
|
1704
1800
|
#
|
1705
|
-
#
|
1706
|
-
# a good idea to set the <tt>:inverse_of</tt> option.
|
1707
|
-
# [
|
1801
|
+
# Setting the <tt>:foreign_key</tt> option prevents automatic detection of the association's
|
1802
|
+
# inverse, so it is generally a good idea to set the <tt>:inverse_of</tt> option as well.
|
1803
|
+
# [+:foreign_type+]
|
1708
1804
|
# Specify the column used to store the associated object's type, if this is a polymorphic
|
1709
1805
|
# association. By default this is guessed to be the name of the association with a "_type"
|
1710
1806
|
# suffix. So a class that defines a <tt>belongs_to :taggable, polymorphic: true</tt>
|
1711
1807
|
# association will use "taggable_type" as the default <tt>:foreign_type</tt>.
|
1712
|
-
# [
|
1808
|
+
# [+:primary_key+]
|
1713
1809
|
# Specify the method that returns the primary key of associated object used for the association.
|
1714
1810
|
# By default this is +id+.
|
1715
|
-
# [
|
1811
|
+
# [+:dependent+]
|
1716
1812
|
# If set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to
|
1717
1813
|
# <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method. If set to
|
1718
1814
|
# <tt>:destroy_async</tt>, the associated object is scheduled to be destroyed in a background job.
|
1719
1815
|
# This option should not be specified when #belongs_to is used in conjunction with
|
1720
1816
|
# a #has_many relationship on another class because of the potential to leave
|
1721
1817
|
# orphaned records behind.
|
1722
|
-
# [
|
1818
|
+
# [+:counter_cache+]
|
1723
1819
|
# Caches the number of belonging objects on the associate class through the use of CounterCache::ClassMethods#increment_counter
|
1724
1820
|
# and CounterCache::ClassMethods#decrement_counter. The counter cache is incremented when an object of this
|
1725
1821
|
# class is created and decremented when it's destroyed. This requires that a column
|
@@ -1731,14 +1827,14 @@ module ActiveRecord
|
|
1731
1827
|
# option (e.g., <tt>counter_cache: :my_custom_counter</tt>.)
|
1732
1828
|
# Note: Specifying a counter cache will add it to that model's list of readonly attributes
|
1733
1829
|
# using +attr_readonly+.
|
1734
|
-
# [
|
1830
|
+
# [+:polymorphic+]
|
1735
1831
|
# Specify this association is a polymorphic association by passing +true+.
|
1736
1832
|
# Note: If you've enabled the counter cache, then you may want to add the counter cache attribute
|
1737
1833
|
# to the +attr_readonly+ list in the associated classes (e.g. <tt>class Post; attr_readonly :comments_count; end</tt>).
|
1738
|
-
# [
|
1834
|
+
# [+:validate+]
|
1739
1835
|
# When set to +true+, validates new objects added to association when saving the parent object. +false+ by default.
|
1740
1836
|
# If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
|
1741
|
-
# [
|
1837
|
+
# [+:autosave+]
|
1742
1838
|
# If true, always save the associated object or destroy it if marked for destruction, when
|
1743
1839
|
# saving the parent object.
|
1744
1840
|
# If false, never save or destroy the associated object.
|
@@ -1746,32 +1842,37 @@ module ActiveRecord
|
|
1746
1842
|
#
|
1747
1843
|
# Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for
|
1748
1844
|
# sets <tt>:autosave</tt> to <tt>true</tt>.
|
1749
|
-
# [
|
1750
|
-
# If true, the associated object will be touched (the updated_at/
|
1845
|
+
# [+:touch+]
|
1846
|
+
# If true, the associated object will be touched (the +updated_at+ / +updated_on+ attributes set to current time)
|
1751
1847
|
# when this record is either saved or destroyed. If you specify a symbol, that attribute
|
1752
|
-
# will be updated with the current time in addition to the updated_at/
|
1753
|
-
# Please note that
|
1754
|
-
# +after_commit
|
1755
|
-
# [
|
1848
|
+
# will be updated with the current time in addition to the +updated_at+ / +updated_on+ attribute.
|
1849
|
+
# Please note that no validation will be performed when touching, and only the +after_touch+,
|
1850
|
+
# +after_commit+, and +after_rollback+ callbacks will be executed.
|
1851
|
+
# [+:inverse_of+]
|
1756
1852
|
# Specifies the name of the #has_one or #has_many association on the associated
|
1757
1853
|
# object that is the inverse of this #belongs_to association.
|
1758
1854
|
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
|
1759
|
-
# [
|
1855
|
+
# [+:optional+]
|
1760
1856
|
# When set to +true+, the association will not have its presence validated.
|
1761
|
-
# [
|
1857
|
+
# [+:required+]
|
1762
1858
|
# When set to +true+, the association will also have its presence validated.
|
1763
1859
|
# This will validate the association itself, not the id. You can use
|
1764
1860
|
# +:inverse_of+ to avoid an extra query during validation.
|
1765
1861
|
# NOTE: <tt>required</tt> is set to <tt>true</tt> by default and is deprecated. If
|
1766
1862
|
# you don't want to have association presence validated, use <tt>optional: true</tt>.
|
1767
|
-
# [
|
1863
|
+
# [+:default+]
|
1768
1864
|
# Provide a callable (i.e. proc or lambda) to specify that the association should
|
1769
1865
|
# be initialized with a particular record before validation.
|
1770
|
-
#
|
1866
|
+
# Please note that callable won't be executed if the record exists.
|
1867
|
+
# [+:strict_loading+]
|
1771
1868
|
# Enforces strict loading every time the associated record is loaded through this association.
|
1772
|
-
# [
|
1869
|
+
# [+:ensuring_owner_was+]
|
1773
1870
|
# Specifies an instance method to be called on the owner. The method must return true in order for the
|
1774
1871
|
# associated records to be deleted in a background job.
|
1872
|
+
# [+:query_constraints+]
|
1873
|
+
# Serves as a composite foreign key. Defines the list of columns to be used to query the associated object.
|
1874
|
+
# This is an optional option. By default Rails will attempt to derive the value automatically.
|
1875
|
+
# When the value is set the Array size must match associated model's primary key or +query_constraints+ size.
|
1775
1876
|
#
|
1776
1877
|
# Option examples:
|
1777
1878
|
# belongs_to :firm, foreign_key: "client_of"
|
@@ -1787,6 +1888,7 @@ module ActiveRecord
|
|
1787
1888
|
# belongs_to :user, optional: true
|
1788
1889
|
# belongs_to :account, default: -> { company.account }
|
1789
1890
|
# belongs_to :account, strict_loading: true
|
1891
|
+
# belong_to :note, query_constraints: [:organization_id, :note_id]
|
1790
1892
|
def belongs_to(name, scope = nil, **options)
|
1791
1893
|
reflection = Builder::BelongsTo.build(self, name, scope, options)
|
1792
1894
|
Reflection.add_reflection self, name, reflection
|
@@ -1809,7 +1911,7 @@ module ActiveRecord
|
|
1809
1911
|
# The join table should not have a primary key or a model associated with it. You must manually generate the
|
1810
1912
|
# join table with a migration such as this:
|
1811
1913
|
#
|
1812
|
-
# class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration[7.
|
1914
|
+
# class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration[7.1]
|
1813
1915
|
# def change
|
1814
1916
|
# create_join_table :developers, :projects
|
1815
1917
|
# end
|
@@ -1824,71 +1926,80 @@ module ActiveRecord
|
|
1824
1926
|
# +collection+ is a placeholder for the symbol passed as the +name+ argument, so
|
1825
1927
|
# <tt>has_and_belongs_to_many :categories</tt> would add among others <tt>categories.empty?</tt>.
|
1826
1928
|
#
|
1827
|
-
# [collection]
|
1929
|
+
# [<tt>collection</tt>]
|
1828
1930
|
# Returns a Relation of all the associated objects.
|
1829
1931
|
# An empty Relation is returned if none are found.
|
1830
|
-
# [collection<<(object, ...)]
|
1932
|
+
# [<tt>collection<<(object, ...)</tt>]
|
1831
1933
|
# Adds one or more objects to the collection by creating associations in the join table
|
1832
1934
|
# (<tt>collection.push</tt> and <tt>collection.concat</tt> are aliases to this method).
|
1833
1935
|
# Note that this operation instantly fires update SQL without waiting for the save or update call on the
|
1834
1936
|
# parent object, unless the parent object is a new record.
|
1835
|
-
# [collection.delete(object, ...)]
|
1937
|
+
# [<tt>collection.delete(object, ...)</tt>]
|
1836
1938
|
# Removes one or more objects from the collection by removing their associations from the join table.
|
1837
1939
|
# This does not destroy the objects.
|
1838
|
-
# [collection.destroy(object, ...)]
|
1940
|
+
# [<tt>collection.destroy(object, ...)</tt>]
|
1839
1941
|
# Removes one or more objects from the collection by running destroy on each association in the join table, overriding any dependent option.
|
1840
1942
|
# This does not destroy the objects.
|
1841
|
-
# [collection=objects]
|
1943
|
+
# [<tt>collection=objects</tt>]
|
1842
1944
|
# Replaces the collection's content by deleting and adding objects as appropriate.
|
1843
|
-
# [collection_singular_ids]
|
1945
|
+
# [<tt>collection_singular_ids</tt>]
|
1844
1946
|
# Returns an array of the associated objects' ids.
|
1845
|
-
# [collection_singular_ids=ids]
|
1947
|
+
# [<tt>collection_singular_ids=ids</tt>]
|
1846
1948
|
# Replace the collection by the objects identified by the primary keys in +ids+.
|
1847
|
-
# [collection.clear]
|
1949
|
+
# [<tt>collection.clear</tt>]
|
1848
1950
|
# Removes every object from the collection. This does not destroy the objects.
|
1849
|
-
# [collection.empty
|
1951
|
+
# [<tt>collection.empty?</tt>]
|
1850
1952
|
# Returns +true+ if there are no associated objects.
|
1851
|
-
# [collection.size]
|
1953
|
+
# [<tt>collection.size</tt>]
|
1852
1954
|
# Returns the number of associated objects.
|
1853
|
-
# [collection.find(id)]
|
1955
|
+
# [<tt>collection.find(id)</tt>]
|
1854
1956
|
# Finds an associated object responding to the +id+ and that
|
1855
1957
|
# meets the condition that it has to be associated with this object.
|
1856
1958
|
# Uses the same rules as ActiveRecord::FinderMethods#find.
|
1857
|
-
# [collection.exists?(...)]
|
1959
|
+
# [<tt>collection.exists?(...)</tt>]
|
1858
1960
|
# Checks whether an associated object with the given conditions exists.
|
1859
1961
|
# Uses the same rules as ActiveRecord::FinderMethods#exists?.
|
1860
|
-
# [collection.build(attributes = {})]
|
1962
|
+
# [<tt>collection.build(attributes = {})</tt>]
|
1861
1963
|
# Returns a new object of the collection type that has been instantiated
|
1862
1964
|
# with +attributes+ and linked to this object through the join table, but has not yet been saved.
|
1863
|
-
# [collection.create(attributes = {})]
|
1965
|
+
# [<tt>collection.create(attributes = {})</tt>]
|
1864
1966
|
# Returns a new object of the collection type that has been instantiated
|
1865
1967
|
# with +attributes+, linked to this object through the join table, and that has already been
|
1866
1968
|
# saved (if it passed the validation).
|
1867
|
-
# [collection.reload]
|
1969
|
+
# [<tt>collection.reload</tt>]
|
1868
1970
|
# Returns a Relation of all of the associated objects, forcing a database read.
|
1869
1971
|
# An empty Relation is returned if none are found.
|
1870
1972
|
#
|
1871
|
-
#
|
1872
|
-
#
|
1873
|
-
#
|
1874
|
-
#
|
1875
|
-
#
|
1876
|
-
#
|
1877
|
-
#
|
1878
|
-
#
|
1879
|
-
#
|
1880
|
-
#
|
1881
|
-
#
|
1882
|
-
#
|
1883
|
-
#
|
1884
|
-
#
|
1885
|
-
#
|
1886
|
-
#
|
1887
|
-
#
|
1888
|
-
#
|
1973
|
+
# ==== Example
|
1974
|
+
#
|
1975
|
+
# class Developer < ActiveRecord::Base
|
1976
|
+
# has_and_belongs_to_many :projects
|
1977
|
+
# end
|
1978
|
+
#
|
1979
|
+
# Declaring <tt>has_and_belongs_to_many :projects</tt> adds the following methods (and more):
|
1980
|
+
#
|
1981
|
+
# developer = Developer.find(11)
|
1982
|
+
# project = Project.find(9)
|
1983
|
+
#
|
1984
|
+
# developer.projects
|
1985
|
+
# developer.projects << project
|
1986
|
+
# developer.projects.delete(project)
|
1987
|
+
# developer.projects.destroy(project)
|
1988
|
+
# developer.projects = [project]
|
1989
|
+
# developer.project_ids
|
1990
|
+
# developer.project_ids = [9]
|
1991
|
+
# developer.projects.clear
|
1992
|
+
# developer.projects.empty?
|
1993
|
+
# developer.projects.size
|
1994
|
+
# developer.projects.find(9)
|
1995
|
+
# developer.projects.exists?(9)
|
1996
|
+
# developer.projects.build # similar to Project.new(developer_id: 11)
|
1997
|
+
# developer.projects.create # similar to Project.create(developer_id: 11)
|
1998
|
+
# developer.projects.reload
|
1999
|
+
#
|
1889
2000
|
# The declaration may include an +options+ hash to specialize the behavior of the association.
|
1890
2001
|
#
|
1891
|
-
#
|
2002
|
+
# ==== Scopes
|
1892
2003
|
#
|
1893
2004
|
# You can pass a second argument +scope+ as a callable (i.e. proc or
|
1894
2005
|
# lambda) to retrieve a specific set of records or customize the generated
|
@@ -1900,7 +2011,7 @@ module ActiveRecord
|
|
1900
2011
|
# where("default_category = ?", post.default_category)
|
1901
2012
|
# }
|
1902
2013
|
#
|
1903
|
-
#
|
2014
|
+
# ==== Extensions
|
1904
2015
|
#
|
1905
2016
|
# The +extension+ argument allows you to pass a block into a
|
1906
2017
|
# has_and_belongs_to_many association. This is useful for adding new
|
@@ -1915,33 +2026,33 @@ module ActiveRecord
|
|
1915
2026
|
# end
|
1916
2027
|
# end
|
1917
2028
|
#
|
1918
|
-
#
|
2029
|
+
# ==== Options
|
1919
2030
|
#
|
1920
|
-
# [
|
2031
|
+
# [+:class_name+]
|
1921
2032
|
# Specify the class name of the association. Use it only if that name can't be inferred
|
1922
2033
|
# from the association name. So <tt>has_and_belongs_to_many :projects</tt> will by default be linked to the
|
1923
2034
|
# Project class, but if the real class name is SuperProject, you'll have to specify it with this option.
|
1924
|
-
# [
|
2035
|
+
# [+:join_table+]
|
1925
2036
|
# Specify the name of the join table if the default based on lexical order isn't what you want.
|
1926
2037
|
# <b>WARNING:</b> If you're overwriting the table name of either class, the +table_name+ method
|
1927
2038
|
# MUST be declared underneath any #has_and_belongs_to_many declaration in order to work.
|
1928
|
-
# [
|
2039
|
+
# [+:foreign_key+]
|
1929
2040
|
# Specify the foreign key used for the association. By default this is guessed to be the name
|
1930
2041
|
# of this class in lower-case and "_id" suffixed. So a Person class that makes
|
1931
2042
|
# a #has_and_belongs_to_many association to Project will use "person_id" as the
|
1932
2043
|
# default <tt>:foreign_key</tt>.
|
1933
2044
|
#
|
1934
|
-
#
|
1935
|
-
# a good idea to set the <tt>:inverse_of</tt> option.
|
1936
|
-
# [
|
2045
|
+
# Setting the <tt>:foreign_key</tt> option prevents automatic detection of the association's
|
2046
|
+
# inverse, so it is generally a good idea to set the <tt>:inverse_of</tt> option as well.
|
2047
|
+
# [+:association_foreign_key+]
|
1937
2048
|
# Specify the foreign key used for the association on the receiving side of the association.
|
1938
2049
|
# By default this is guessed to be the name of the associated class in lower-case and "_id" suffixed.
|
1939
2050
|
# So if a Person class makes a #has_and_belongs_to_many association to Project,
|
1940
2051
|
# the association will use "project_id" as the default <tt>:association_foreign_key</tt>.
|
1941
|
-
# [
|
2052
|
+
# [+:validate+]
|
1942
2053
|
# When set to +true+, validates new objects added to association when saving the parent object. +true+ by default.
|
1943
2054
|
# If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
|
1944
|
-
# [
|
2055
|
+
# [+:autosave+]
|
1945
2056
|
# If true, always save the associated objects or destroy them if marked for destruction, when
|
1946
2057
|
# saving the parent object.
|
1947
2058
|
# If false, never save or destroy the associated objects.
|
@@ -1949,7 +2060,7 @@ module ActiveRecord
|
|
1949
2060
|
#
|
1950
2061
|
# Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
|
1951
2062
|
# <tt>:autosave</tt> to <tt>true</tt>.
|
1952
|
-
# [
|
2063
|
+
# [+:strict_loading+]
|
1953
2064
|
# Enforces strict loading every time an associated record is loaded through this association.
|
1954
2065
|
#
|
1955
2066
|
# Option examples:
|