activerecord 7.0.8 → 7.1.3.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 +1546 -1454
- data/MIT-LICENSE +1 -1
- data/README.rdoc +16 -16
- 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 +15 -9
- data/lib/active_record/associations/collection_proxy.rb +15 -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.rb +10 -8
- data/lib/active_record/associations/preloader/association.rb +31 -7
- 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 +313 -217
- 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 +150 -31
- data/lib/active_record/attribute_methods/write.rb +3 -3
- data/lib/active_record/attribute_methods.rb +105 -21
- data/lib/active_record/attributes.rb +3 -3
- data/lib/active_record/autosave_association.rb +55 -9
- data/lib/active_record/base.rb +7 -2
- data/lib/active_record/callbacks.rb +10 -24
- 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 +74 -51
- 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 +41 -6
- 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 +137 -11
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +289 -124
- data/lib/active_record/connection_adapters/abstract/transaction.rb +287 -58
- data/lib/active_record/connection_adapters/abstract_adapter.rb +511 -91
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +207 -108
- 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 +22 -143
- data/lib/active_record/connection_adapters/mysql/quoting.rb +16 -12
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +6 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +18 -13
- 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 +14 -3
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +74 -40
- 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 +1 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +10 -6
- 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 +361 -60
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +353 -192
- 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 +4 -3
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +1 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +26 -7
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +209 -79
- 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 +262 -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 +175 -153
- data/lib/active_record/counter_cache.rb +46 -25
- 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 +86 -33
- 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/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 +21 -6
- 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 +19 -22
- data/lib/active_record/encryption.rb +1 -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/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 +31 -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/pessimistic.rb +5 -2
- data/lib/active_record/log_subscriber.rb +29 -12
- 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 +6 -8
- data/lib/active_record/middleware/shard_selector.rb +3 -1
- data/lib/active_record/migration/command_recorder.rb +104 -5
- data/lib/active_record/migration/compatibility.rb +139 -5
- 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 +219 -111
- data/lib/active_record/model_schema.rb +64 -44
- data/lib/active_record/nested_attributes.rb +24 -6
- data/lib/active_record/normalization.rb +167 -0
- data/lib/active_record/persistence.rb +188 -37
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +3 -21
- data/lib/active_record/query_logs.rb +77 -52
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +15 -2
- data/lib/active_record/railtie.rb +109 -47
- data/lib/active_record/railties/controller_runtime.rb +12 -6
- data/lib/active_record/railties/databases.rake +142 -148
- 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 +174 -44
- 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 +187 -63
- 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 +11 -2
- 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 +2 -1
- data/lib/active_record/relation/query_methods.rb +352 -63
- data/lib/active_record/relation/spawn_methods.rb +18 -1
- data/lib/active_record/relation.rb +91 -35
- data/lib/active_record/result.rb +19 -5
- 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 +46 -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 +8 -8
- data/lib/active_record/suppressor.rb +3 -1
- data/lib/active_record/table_metadata.rb +10 -1
- data/lib/active_record/tasks/database_tasks.rb +127 -105
- 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 +113 -96
- 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 +36 -10
- 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/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 +121 -16
- data/lib/arel/errors.rb +10 -0
- data/lib/arel/factory_methods.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/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 +48 -12
- 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 |
|
@@ -611,6 +648,7 @@ module ActiveRecord
|
|
611
648
|
# def log_after_remove(record)
|
612
649
|
# # ...
|
613
650
|
# end
|
651
|
+
# end
|
614
652
|
#
|
615
653
|
# It's possible to stack callbacks by passing them as an array. Example:
|
616
654
|
#
|
@@ -1012,7 +1050,7 @@ module ActiveRecord
|
|
1012
1050
|
# query per addressable type.
|
1013
1051
|
# For example, if all the addressables are either of class Person or Company, then a total
|
1014
1052
|
# of 3 queries will be executed. The list of addressable types to load is determined on
|
1015
|
-
# the back of the addresses loaded. This is not supported if Active Record has to
|
1053
|
+
# the back of the addresses loaded. This is not supported if Active Record has to fall back
|
1016
1054
|
# to the previous implementation of eager loading and will raise ActiveRecord::EagerLoadPolymorphicError.
|
1017
1055
|
# The reason is that the parent model's type is a column value so its corresponding table
|
1018
1056
|
# name cannot be put in the +FROM+/+JOIN+ clauses of that query.
|
@@ -1025,45 +1063,45 @@ module ActiveRecord
|
|
1025
1063
|
# Indexes are appended for any more successive uses of the table name.
|
1026
1064
|
#
|
1027
1065
|
# Post.joins(:comments)
|
1028
|
-
# #
|
1066
|
+
# # SELECT ... FROM posts INNER JOIN comments ON ...
|
1029
1067
|
# Post.joins(:special_comments) # STI
|
1030
|
-
# #
|
1068
|
+
# # SELECT ... FROM posts INNER JOIN comments ON ... AND comments.type = 'SpecialComment'
|
1031
1069
|
# Post.joins(:comments, :special_comments) # special_comments is the reflection name, posts is the parent table name
|
1032
|
-
# #
|
1070
|
+
# # SELECT ... FROM posts INNER JOIN comments ON ... INNER JOIN comments special_comments_posts
|
1033
1071
|
#
|
1034
1072
|
# Acts as tree example:
|
1035
1073
|
#
|
1036
1074
|
# TreeMixin.joins(:children)
|
1037
|
-
# #
|
1075
|
+
# # SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
|
1038
1076
|
# TreeMixin.joins(children: :parent)
|
1039
|
-
# #
|
1040
|
-
#
|
1077
|
+
# # SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
|
1078
|
+
# # INNER JOIN parents_mixins ...
|
1041
1079
|
# TreeMixin.joins(children: {parent: :children})
|
1042
|
-
# #
|
1043
|
-
#
|
1044
|
-
#
|
1080
|
+
# # SELECT ... FROM mixins INNER JOIN mixins childrens_mixins ...
|
1081
|
+
# # INNER JOIN parents_mixins ...
|
1082
|
+
# # INNER JOIN mixins childrens_mixins_2
|
1045
1083
|
#
|
1046
1084
|
# Has and Belongs to Many join tables use the same idea, but add a <tt>_join</tt> suffix:
|
1047
1085
|
#
|
1048
1086
|
# Post.joins(:categories)
|
1049
|
-
# #
|
1087
|
+
# # SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
|
1050
1088
|
# Post.joins(categories: :posts)
|
1051
|
-
# #
|
1052
|
-
#
|
1089
|
+
# # SELECT ... FROM posts INNER JOIN categories_posts ... INNER JOIN categories ...
|
1090
|
+
# # INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
|
1053
1091
|
# Post.joins(categories: {posts: :categories})
|
1054
|
-
# #
|
1055
|
-
#
|
1056
|
-
#
|
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
|
1057
1095
|
#
|
1058
1096
|
# If you wish to specify your own custom joins using ActiveRecord::QueryMethods#joins method, those table
|
1059
1097
|
# names will take precedence over the eager associations:
|
1060
1098
|
#
|
1061
1099
|
# Post.joins(:comments).joins("inner join comments ...")
|
1062
|
-
# #
|
1100
|
+
# # SELECT ... FROM posts INNER JOIN comments_posts ON ... INNER JOIN comments ...
|
1063
1101
|
# Post.joins(:comments, :special_comments).joins("inner join comments ...")
|
1064
|
-
# #
|
1065
|
-
#
|
1066
|
-
#
|
1102
|
+
# # SELECT ... FROM posts INNER JOIN comments comments_posts ON ...
|
1103
|
+
# # INNER JOIN comments special_comments_posts ...
|
1104
|
+
# # INNER JOIN comments ...
|
1067
1105
|
#
|
1068
1106
|
# Table aliases are automatically truncated according to the maximum length of table identifiers
|
1069
1107
|
# according to the specific database.
|
@@ -1144,7 +1182,8 @@ module ActiveRecord
|
|
1144
1182
|
# belongs_to :dungeon, inverse_of: :evil_wizard
|
1145
1183
|
# end
|
1146
1184
|
#
|
1147
|
-
# 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].
|
1148
1187
|
#
|
1149
1188
|
# == Deleting from associations
|
1150
1189
|
#
|
@@ -1166,7 +1205,7 @@ module ActiveRecord
|
|
1166
1205
|
# specific association types. When no option is given, the behavior is to do nothing
|
1167
1206
|
# with the associated records when destroying a record.
|
1168
1207
|
#
|
1169
|
-
# Note that <tt>:dependent</tt> is implemented using Rails' callback
|
1208
|
+
# Note that <tt>:dependent</tt> is implemented using \Rails' callback
|
1170
1209
|
# system, which works by processing callbacks in order. Therefore, other
|
1171
1210
|
# callbacks declared either before or after the <tt>:dependent</tt> option
|
1172
1211
|
# can affect what it does.
|
@@ -1237,15 +1276,15 @@ module ActiveRecord
|
|
1237
1276
|
# +collection+ is a placeholder for the symbol passed as the +name+ argument, so
|
1238
1277
|
# <tt>has_many :clients</tt> would add among others <tt>clients.empty?</tt>.
|
1239
1278
|
#
|
1240
|
-
# [collection]
|
1279
|
+
# [<tt>collection</tt>]
|
1241
1280
|
# Returns a Relation of all the associated objects.
|
1242
1281
|
# An empty Relation is returned if none are found.
|
1243
|
-
# [collection<<(object, ...)]
|
1282
|
+
# [<tt>collection<<(object, ...)</tt>]
|
1244
1283
|
# Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
|
1245
1284
|
# Note that this operation instantly fires update SQL without waiting for the save or update call on the
|
1246
1285
|
# parent object, unless the parent object is a new record.
|
1247
1286
|
# This will also run validations and callbacks of associated object(s).
|
1248
|
-
# [collection.delete(object, ...)]
|
1287
|
+
# [<tt>collection.delete(object, ...)</tt>]
|
1249
1288
|
# Removes one or more objects from the collection by setting their foreign keys to +NULL+.
|
1250
1289
|
# Objects will be in addition destroyed if they're associated with <tt>dependent: :destroy</tt>,
|
1251
1290
|
# and deleted if they're associated with <tt>dependent: :delete_all</tt>.
|
@@ -1253,75 +1292,84 @@ module ActiveRecord
|
|
1253
1292
|
# If the <tt>:through</tt> option is used, then the join records are deleted (rather than
|
1254
1293
|
# nullified) by default, but you can specify <tt>dependent: :destroy</tt> or
|
1255
1294
|
# <tt>dependent: :nullify</tt> to override this.
|
1256
|
-
# [collection.destroy(object, ...)]
|
1295
|
+
# [<tt>collection.destroy(object, ...)</tt>]
|
1257
1296
|
# Removes one or more objects from the collection by running <tt>destroy</tt> on
|
1258
1297
|
# each record, regardless of any dependent option, ensuring callbacks are run.
|
1259
1298
|
#
|
1260
1299
|
# If the <tt>:through</tt> option is used, then the join records are destroyed
|
1261
1300
|
# instead, not the objects themselves.
|
1262
|
-
# [collection=objects]
|
1301
|
+
# [<tt>collection=objects</tt>]
|
1263
1302
|
# Replaces the collections content by deleting and adding objects as appropriate. If the <tt>:through</tt>
|
1264
1303
|
# option is true callbacks in the join models are triggered except destroy callbacks, since deletion is
|
1265
1304
|
# direct by default. You can specify <tt>dependent: :destroy</tt> or
|
1266
1305
|
# <tt>dependent: :nullify</tt> to override this.
|
1267
|
-
# [collection_singular_ids]
|
1306
|
+
# [<tt>collection_singular_ids</tt>]
|
1268
1307
|
# Returns an array of the associated objects' ids
|
1269
|
-
# [collection_singular_ids=ids]
|
1308
|
+
# [<tt>collection_singular_ids=ids</tt>]
|
1270
1309
|
# Replace the collection with the objects identified by the primary keys in +ids+. This
|
1271
1310
|
# method loads the models and calls <tt>collection=</tt>. See above.
|
1272
|
-
# [collection.clear]
|
1311
|
+
# [<tt>collection.clear</tt>]
|
1273
1312
|
# Removes every object from the collection. This destroys the associated objects if they
|
1274
1313
|
# are associated with <tt>dependent: :destroy</tt>, deletes them directly from the
|
1275
1314
|
# database if <tt>dependent: :delete_all</tt>, otherwise sets their foreign keys to +NULL+.
|
1276
1315
|
# If the <tt>:through</tt> option is true no destroy callbacks are invoked on the join models.
|
1277
1316
|
# Join models are directly deleted.
|
1278
|
-
# [collection.empty
|
1317
|
+
# [<tt>collection.empty?</tt>]
|
1279
1318
|
# Returns +true+ if there are no associated objects.
|
1280
|
-
# [collection.size]
|
1319
|
+
# [<tt>collection.size</tt>]
|
1281
1320
|
# Returns the number of associated objects.
|
1282
|
-
# [collection.find(...)]
|
1321
|
+
# [<tt>collection.find(...)</tt>]
|
1283
1322
|
# Finds an associated object according to the same rules as ActiveRecord::FinderMethods#find.
|
1284
|
-
# [collection.exists?(...)]
|
1323
|
+
# [<tt>collection.exists?(...)</tt>]
|
1285
1324
|
# Checks whether an associated object with the given conditions exists.
|
1286
1325
|
# Uses the same rules as ActiveRecord::FinderMethods#exists?.
|
1287
|
-
# [collection.build(attributes = {}, ...)]
|
1326
|
+
# [<tt>collection.build(attributes = {}, ...)</tt>]
|
1288
1327
|
# Returns one or more new objects of the collection type that have been instantiated
|
1289
1328
|
# with +attributes+ and linked to this object through a foreign key, but have not yet
|
1290
1329
|
# been saved.
|
1291
|
-
# [collection.create(attributes = {})]
|
1330
|
+
# [<tt>collection.create(attributes = {})</tt>]
|
1292
1331
|
# Returns a new object of the collection type that has been instantiated
|
1293
1332
|
# with +attributes+, linked to this object through a foreign key, and that has already
|
1294
1333
|
# been saved (if it passed the validation). *Note*: This only works if the base model
|
1295
1334
|
# already exists in the DB, not if it is a new (unsaved) record!
|
1296
|
-
# [collection.create!(attributes = {})]
|
1335
|
+
# [<tt>collection.create!(attributes = {})</tt>]
|
1297
1336
|
# Does the same as <tt>collection.create</tt>, but raises ActiveRecord::RecordInvalid
|
1298
1337
|
# if the record is invalid.
|
1299
|
-
# [collection.reload]
|
1338
|
+
# [<tt>collection.reload</tt>]
|
1300
1339
|
# Returns a Relation of all of the associated objects, forcing a database read.
|
1301
1340
|
# An empty Relation is returned if none are found.
|
1302
1341
|
#
|
1303
|
-
#
|
1304
|
-
#
|
1305
|
-
#
|
1306
|
-
#
|
1307
|
-
#
|
1308
|
-
#
|
1309
|
-
#
|
1310
|
-
#
|
1311
|
-
#
|
1312
|
-
#
|
1313
|
-
#
|
1314
|
-
#
|
1315
|
-
#
|
1316
|
-
#
|
1317
|
-
#
|
1318
|
-
#
|
1319
|
-
#
|
1320
|
-
#
|
1321
|
-
#
|
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
|
+
#
|
1322
1370
|
# The declaration can also include an +options+ hash to specialize the behavior of the association.
|
1323
1371
|
#
|
1324
|
-
#
|
1372
|
+
# ==== Scopes
|
1325
1373
|
#
|
1326
1374
|
# You can pass a second argument +scope+ as a callable (i.e. proc or
|
1327
1375
|
# lambda) to retrieve a specific set of records or customize the generated
|
@@ -1332,7 +1380,7 @@ module ActiveRecord
|
|
1332
1380
|
# has_many :employees, -> { joins(:address) }
|
1333
1381
|
# has_many :posts, ->(blog) { where("max_post_length > ?", blog.max_post_length) }
|
1334
1382
|
#
|
1335
|
-
#
|
1383
|
+
# ==== Extensions
|
1336
1384
|
#
|
1337
1385
|
# The +extension+ argument allows you to pass a block into a has_many
|
1338
1386
|
# association. This is useful for adding new finders, creators, and other
|
@@ -1346,31 +1394,31 @@ module ActiveRecord
|
|
1346
1394
|
# end
|
1347
1395
|
# end
|
1348
1396
|
#
|
1349
|
-
#
|
1350
|
-
# [
|
1397
|
+
# ==== Options
|
1398
|
+
# [+:class_name+]
|
1351
1399
|
# Specify the class name of the association. Use it only if that name can't be inferred
|
1352
1400
|
# from the association name. So <tt>has_many :products</tt> will by default be linked
|
1353
1401
|
# to the +Product+ class, but if the real class name is +SpecialProduct+, you'll have to
|
1354
1402
|
# specify it with this option.
|
1355
|
-
# [
|
1403
|
+
# [+:foreign_key+]
|
1356
1404
|
# Specify the foreign key used for the association. By default this is guessed to be the name
|
1357
1405
|
# of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_many
|
1358
1406
|
# association will use "person_id" as the default <tt>:foreign_key</tt>.
|
1359
1407
|
#
|
1360
|
-
#
|
1361
|
-
# a good idea to set the <tt>:inverse_of</tt> option.
|
1362
|
-
# [
|
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+]
|
1363
1411
|
# Specify the column used to store the associated object's type, if this is a polymorphic
|
1364
1412
|
# association. By default this is guessed to be the name of the polymorphic association
|
1365
1413
|
# specified on "as" option with a "_type" suffix. So a class that defines a
|
1366
1414
|
# <tt>has_many :tags, as: :taggable</tt> association will use "taggable_type" as the
|
1367
1415
|
# default <tt>:foreign_type</tt>.
|
1368
|
-
# [
|
1416
|
+
# [+:primary_key+]
|
1369
1417
|
# Specify the name of the column to use as the primary key for the association. By default this is +id+.
|
1370
|
-
# [
|
1418
|
+
# [+:dependent+]
|
1371
1419
|
# Controls what happens to the associated objects when
|
1372
1420
|
# their owner is destroyed. Note that these are implemented as
|
1373
|
-
# callbacks, and Rails executes callbacks in order. Therefore, other
|
1421
|
+
# callbacks, and \Rails executes callbacks in order. Therefore, other
|
1374
1422
|
# similar callbacks may affect the <tt>:dependent</tt> behavior, and the
|
1375
1423
|
# <tt>:dependent</tt> behavior may affect other callbacks.
|
1376
1424
|
#
|
@@ -1382,7 +1430,7 @@ module ActiveRecord
|
|
1382
1430
|
# * <tt>:delete_all</tt> causes all the associated objects to be deleted directly from the database (so callbacks will not be executed).
|
1383
1431
|
# * <tt>:nullify</tt> causes the foreign keys to be set to +NULL+. Polymorphic type will also be nullified
|
1384
1432
|
# on polymorphic associations. Callbacks are not executed.
|
1385
|
-
# * <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.
|
1386
1434
|
# * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there are any associated objects.
|
1387
1435
|
#
|
1388
1436
|
# If using with the <tt>:through</tt> option, the association on the join model must be
|
@@ -1394,12 +1442,12 @@ module ActiveRecord
|
|
1394
1442
|
# <tt>has_many :comments, -> { where published: true }, dependent: :destroy</tt> and <tt>destroy</tt> is
|
1395
1443
|
# called on a post, only published comments are destroyed. This means that any unpublished comments in the
|
1396
1444
|
# database would still contain a foreign key pointing to the now deleted post.
|
1397
|
-
# [
|
1445
|
+
# [+:counter_cache+]
|
1398
1446
|
# This option can be used to configure a custom named <tt>:counter_cache.</tt> You only need this option,
|
1399
1447
|
# when you customized the name of your <tt>:counter_cache</tt> on the #belongs_to association.
|
1400
|
-
# [
|
1448
|
+
# [+:as+]
|
1401
1449
|
# Specifies a polymorphic interface (See #belongs_to).
|
1402
|
-
# [
|
1450
|
+
# [+:through+]
|
1403
1451
|
# Specifies an association through which to perform the query. This can be any other type
|
1404
1452
|
# of association, including other <tt>:through</tt> associations. Options for <tt>:class_name</tt>,
|
1405
1453
|
# <tt>:primary_key</tt> and <tt>:foreign_key</tt> are ignored, as the association uses the
|
@@ -1414,24 +1462,24 @@ module ActiveRecord
|
|
1414
1462
|
# a good idea to set the <tt>:inverse_of</tt> option on the source association on the
|
1415
1463
|
# join model. This allows associated records to be built which will automatically create
|
1416
1464
|
# the appropriate join model records when they are saved. (See the 'Association Join Models'
|
1417
|
-
#
|
1418
|
-
# [
|
1465
|
+
# and 'Setting Inverses' sections above.)
|
1466
|
+
# [+:disable_joins+]
|
1419
1467
|
# Specifies whether joins should be skipped for an association. If set to true, two or more queries
|
1420
1468
|
# will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory
|
1421
1469
|
# due to database limitations. This option is only applicable on <tt>has_many :through</tt> associations as
|
1422
1470
|
# +has_many+ alone do not perform a join.
|
1423
|
-
# [
|
1471
|
+
# [+:source+]
|
1424
1472
|
# Specifies the source association name used by #has_many <tt>:through</tt> queries.
|
1425
1473
|
# Only use it if the name cannot be inferred from the association.
|
1426
1474
|
# <tt>has_many :subscribers, through: :subscriptions</tt> will look for either <tt>:subscribers</tt> or
|
1427
1475
|
# <tt>:subscriber</tt> on Subscription, unless a <tt>:source</tt> is given.
|
1428
|
-
# [
|
1476
|
+
# [+:source_type+]
|
1429
1477
|
# Specifies type of the source association used by #has_many <tt>:through</tt> queries where the source
|
1430
1478
|
# association is a polymorphic #belongs_to.
|
1431
|
-
# [
|
1479
|
+
# [+:validate+]
|
1432
1480
|
# When set to +true+, validates new objects added to association when saving the parent object. +true+ by default.
|
1433
1481
|
# If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
|
1434
|
-
# [
|
1482
|
+
# [+:autosave+]
|
1435
1483
|
# If true, always save the associated objects or destroy them if marked for destruction,
|
1436
1484
|
# when saving the parent object. If false, never save or destroy the associated objects.
|
1437
1485
|
# By default, only save associated objects that are new records. This option is implemented as a
|
@@ -1440,20 +1488,24 @@ module ActiveRecord
|
|
1440
1488
|
#
|
1441
1489
|
# Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
|
1442
1490
|
# <tt>:autosave</tt> to <tt>true</tt>.
|
1443
|
-
# [
|
1491
|
+
# [+:inverse_of+]
|
1444
1492
|
# Specifies the name of the #belongs_to association on the associated object
|
1445
1493
|
# that is the inverse of this #has_many association.
|
1446
1494
|
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
|
1447
|
-
# [
|
1495
|
+
# [+:extend+]
|
1448
1496
|
# Specifies a module or array of modules that will be extended into the association object returned.
|
1449
1497
|
# Useful for defining methods on associations, especially when they should be shared between multiple
|
1450
1498
|
# association objects.
|
1451
|
-
# [
|
1499
|
+
# [+:strict_loading+]
|
1452
1500
|
# When set to +true+, enforces strict loading every time the associated record is loaded through this
|
1453
1501
|
# association.
|
1454
|
-
# [
|
1502
|
+
# [+:ensuring_owner_was+]
|
1455
1503
|
# Specifies an instance method to be called on the owner. The method must return true in order for the
|
1456
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.
|
1457
1509
|
#
|
1458
1510
|
# Option examples:
|
1459
1511
|
# has_many :comments, -> { order("posted_on") }
|
@@ -1466,6 +1518,7 @@ module ActiveRecord
|
|
1466
1518
|
# has_many :subscribers, through: :subscriptions, source: :user
|
1467
1519
|
# has_many :subscribers, through: :subscriptions, disable_joins: true
|
1468
1520
|
# has_many :comments, strict_loading: true
|
1521
|
+
# has_many :comments, query_constraints: [:blog_id, :post_id]
|
1469
1522
|
def has_many(name, scope = nil, **options, &extension)
|
1470
1523
|
reflection = Builder::HasMany.build(self, name, scope, options, &extension)
|
1471
1524
|
Reflection.add_reflection self, name, reflection
|
@@ -1481,37 +1534,48 @@ module ActiveRecord
|
|
1481
1534
|
# +association+ is a placeholder for the symbol passed as the +name+ argument, so
|
1482
1535
|
# <tt>has_one :manager</tt> would add among others <tt>manager.nil?</tt>.
|
1483
1536
|
#
|
1484
|
-
# [association]
|
1537
|
+
# [<tt>association</tt>]
|
1485
1538
|
# Returns the associated object. +nil+ is returned if none is found.
|
1486
|
-
# [association=(associate)]
|
1539
|
+
# [<tt>association=(associate)</tt>]
|
1487
1540
|
# Assigns the associate object, extracts the primary key, sets it as the foreign key,
|
1488
1541
|
# and saves the associate object. To avoid database inconsistencies, permanently deletes an existing
|
1489
1542
|
# associated object when assigning a new one, even if the new one isn't saved to database.
|
1490
|
-
# [build_association(attributes = {})]
|
1543
|
+
# [<tt>build_association(attributes = {})</tt>]
|
1491
1544
|
# Returns a new object of the associated type that has been instantiated
|
1492
1545
|
# with +attributes+ and linked to this object through a foreign key, but has not
|
1493
1546
|
# yet been saved.
|
1494
|
-
# [create_association(attributes = {})]
|
1547
|
+
# [<tt>create_association(attributes = {})</tt>]
|
1495
1548
|
# Returns a new object of the associated type that has been instantiated
|
1496
1549
|
# with +attributes+, linked to this object through a foreign key, and that
|
1497
1550
|
# has already been saved (if it passed the validation).
|
1498
|
-
# [create_association!(attributes = {})]
|
1551
|
+
# [<tt>create_association!(attributes = {})</tt>]
|
1499
1552
|
# Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
|
1500
1553
|
# if the record is invalid.
|
1501
|
-
# [reload_association]
|
1554
|
+
# [<tt>reload_association</tt>]
|
1502
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):
|
1503
1566
|
#
|
1504
|
-
#
|
1567
|
+
# account = Account.find(5)
|
1568
|
+
# beneficiary = Beneficiary.find(8)
|
1505
1569
|
#
|
1506
|
-
#
|
1507
|
-
#
|
1508
|
-
#
|
1509
|
-
#
|
1510
|
-
#
|
1511
|
-
#
|
1512
|
-
#
|
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
|
1513
1577
|
#
|
1514
|
-
#
|
1578
|
+
# ==== Scopes
|
1515
1579
|
#
|
1516
1580
|
# You can pass a second argument +scope+ as a callable (i.e. proc or
|
1517
1581
|
# lambda) to retrieve a specific record or customize the generated query
|
@@ -1522,16 +1586,16 @@ module ActiveRecord
|
|
1522
1586
|
# has_one :employer, -> { joins(:company) }
|
1523
1587
|
# has_one :latest_post, ->(blog) { where("created_at > ?", blog.enabled_at) }
|
1524
1588
|
#
|
1525
|
-
#
|
1589
|
+
# ==== Options
|
1526
1590
|
#
|
1527
1591
|
# The declaration can also include an +options+ hash to specialize the behavior of the association.
|
1528
1592
|
#
|
1529
1593
|
# Options are:
|
1530
|
-
# [
|
1594
|
+
# [+:class_name+]
|
1531
1595
|
# Specify the class name of the association. Use it only if that name can't be inferred
|
1532
1596
|
# from the association name. So <tt>has_one :manager</tt> will by default be linked to the Manager class, but
|
1533
1597
|
# if the real class name is Person, you'll have to specify it with this option.
|
1534
|
-
# [
|
1598
|
+
# [+:dependent+]
|
1535
1599
|
# Controls what happens to the associated object when
|
1536
1600
|
# its owner is destroyed:
|
1537
1601
|
#
|
@@ -1543,28 +1607,28 @@ module ActiveRecord
|
|
1543
1607
|
# * <tt>:delete</tt> causes the associated object to be deleted directly from the database (so callbacks will not execute)
|
1544
1608
|
# * <tt>:nullify</tt> causes the foreign key to be set to +NULL+. Polymorphic type column is also nullified
|
1545
1609
|
# on polymorphic associations. Callbacks are not executed.
|
1546
|
-
# * <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
|
1547
1611
|
# * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there is an associated object
|
1548
1612
|
#
|
1549
1613
|
# Note that <tt>:dependent</tt> option is ignored when using <tt>:through</tt> option.
|
1550
|
-
# [
|
1614
|
+
# [+:foreign_key+]
|
1551
1615
|
# Specify the foreign key used for the association. By default this is guessed to be the name
|
1552
1616
|
# of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_one association
|
1553
1617
|
# will use "person_id" as the default <tt>:foreign_key</tt>.
|
1554
1618
|
#
|
1555
|
-
#
|
1556
|
-
# a good idea to set the <tt>:inverse_of</tt> option.
|
1557
|
-
# [
|
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+]
|
1558
1622
|
# Specify the column used to store the associated object's type, if this is a polymorphic
|
1559
1623
|
# association. By default this is guessed to be the name of the polymorphic association
|
1560
1624
|
# specified on "as" option with a "_type" suffix. So a class that defines a
|
1561
1625
|
# <tt>has_one :tag, as: :taggable</tt> association will use "taggable_type" as the
|
1562
1626
|
# default <tt>:foreign_type</tt>.
|
1563
|
-
# [
|
1627
|
+
# [+:primary_key+]
|
1564
1628
|
# Specify the method that returns the primary key used for the association. By default this is +id+.
|
1565
|
-
# [
|
1629
|
+
# [+:as+]
|
1566
1630
|
# Specifies a polymorphic interface (See #belongs_to).
|
1567
|
-
# [
|
1631
|
+
# [+:through+]
|
1568
1632
|
# Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt>,
|
1569
1633
|
# <tt>:primary_key</tt>, and <tt>:foreign_key</tt> are ignored, as the association uses the
|
1570
1634
|
# source reflection. You can only use a <tt>:through</tt> query through a #has_one
|
@@ -1579,49 +1643,53 @@ module ActiveRecord
|
|
1579
1643
|
# a good idea to set the <tt>:inverse_of</tt> option on the source association on the
|
1580
1644
|
# join model. This allows associated records to be built which will automatically create
|
1581
1645
|
# the appropriate join model records when they are saved. (See the 'Association Join Models'
|
1582
|
-
#
|
1583
|
-
# [
|
1646
|
+
# and 'Setting Inverses' sections above.)
|
1647
|
+
# [+:disable_joins+]
|
1584
1648
|
# Specifies whether joins should be skipped for an association. If set to true, two or more queries
|
1585
1649
|
# will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory
|
1586
1650
|
# due to database limitations. This option is only applicable on <tt>has_one :through</tt> associations as
|
1587
1651
|
# +has_one+ alone does not perform a join.
|
1588
|
-
# [
|
1652
|
+
# [+:source+]
|
1589
1653
|
# Specifies the source association name used by #has_one <tt>:through</tt> queries.
|
1590
1654
|
# Only use it if the name cannot be inferred from the association.
|
1591
1655
|
# <tt>has_one :favorite, through: :favorites</tt> will look for a
|
1592
1656
|
# <tt>:favorite</tt> on Favorite, unless a <tt>:source</tt> is given.
|
1593
|
-
# [
|
1657
|
+
# [+:source_type+]
|
1594
1658
|
# Specifies type of the source association used by #has_one <tt>:through</tt> queries where the source
|
1595
1659
|
# association is a polymorphic #belongs_to.
|
1596
|
-
# [
|
1660
|
+
# [+:validate+]
|
1597
1661
|
# When set to +true+, validates new objects added to association when saving the parent object. +false+ by default.
|
1598
1662
|
# If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
|
1599
|
-
# [
|
1663
|
+
# [+:autosave+]
|
1600
1664
|
# If true, always save the associated object or destroy it if marked for destruction,
|
1601
1665
|
# when saving the parent object. If false, never save or destroy the associated object.
|
1602
1666
|
# By default, only save the associated object if it's a new record.
|
1603
1667
|
#
|
1604
1668
|
# Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
|
1605
1669
|
# <tt>:autosave</tt> to <tt>true</tt>.
|
1606
|
-
# [
|
1670
|
+
# [+:touch+]
|
1607
1671
|
# If true, the associated object will be touched (the +updated_at+ / +updated_on+ attributes set to current time)
|
1608
1672
|
# when this record is either saved or destroyed. If you specify a symbol, that attribute
|
1609
1673
|
# will be updated with the current time in addition to the +updated_at+ / +updated_on+ attribute.
|
1610
1674
|
# Please note that no validation will be performed when touching, and only the +after_touch+,
|
1611
1675
|
# +after_commit+, and +after_rollback+ callbacks will be executed.
|
1612
|
-
# [
|
1676
|
+
# [+:inverse_of+]
|
1613
1677
|
# Specifies the name of the #belongs_to association on the associated object
|
1614
1678
|
# that is the inverse of this #has_one association.
|
1615
1679
|
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
|
1616
|
-
# [
|
1680
|
+
# [+:required+]
|
1617
1681
|
# When set to +true+, the association will also have its presence validated.
|
1618
1682
|
# This will validate the association itself, not the id. You can use
|
1619
1683
|
# +:inverse_of+ to avoid an extra query during validation.
|
1620
|
-
# [
|
1684
|
+
# [+:strict_loading+]
|
1621
1685
|
# Enforces strict loading every time the associated record is loaded through this association.
|
1622
|
-
# [
|
1686
|
+
# [+:ensuring_owner_was+]
|
1623
1687
|
# Specifies an instance method to be called on the owner. The method must return true in order for the
|
1624
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.
|
1625
1693
|
#
|
1626
1694
|
# Option examples:
|
1627
1695
|
# has_one :credit_card, dependent: :destroy # destroys the associated credit card
|
@@ -1636,6 +1704,7 @@ module ActiveRecord
|
|
1636
1704
|
# has_one :primary_address, -> { where(primary: true) }, through: :addressables, source: :addressable
|
1637
1705
|
# has_one :credit_card, required: true
|
1638
1706
|
# has_one :credit_card, strict_loading: true
|
1707
|
+
# has_one :employment_record_book, query_constraints: [:organization_id, :employee_id]
|
1639
1708
|
def has_one(name, scope = nil, **options)
|
1640
1709
|
reflection = Builder::HasOne.build(self, name, scope, options)
|
1641
1710
|
Reflection.add_reflection self, name, reflection
|
@@ -1652,42 +1721,52 @@ module ActiveRecord
|
|
1652
1721
|
# +association+ is a placeholder for the symbol passed as the +name+ argument, so
|
1653
1722
|
# <tt>belongs_to :author</tt> would add among others <tt>author.nil?</tt>.
|
1654
1723
|
#
|
1655
|
-
# [association]
|
1724
|
+
# [<tt>association</tt>]
|
1656
1725
|
# Returns the associated object. +nil+ is returned if none is found.
|
1657
|
-
# [association=(associate)]
|
1726
|
+
# [<tt>association=(associate)</tt>]
|
1658
1727
|
# Assigns the associate object, extracts the primary key, and sets it as the foreign key.
|
1659
1728
|
# No modification or deletion of existing records takes place.
|
1660
|
-
# [build_association(attributes = {})]
|
1729
|
+
# [<tt>build_association(attributes = {})</tt>]
|
1661
1730
|
# Returns a new object of the associated type that has been instantiated
|
1662
1731
|
# with +attributes+ and linked to this object through a foreign key, but has not yet been saved.
|
1663
|
-
# [create_association(attributes = {})]
|
1732
|
+
# [<tt>create_association(attributes = {})</tt>]
|
1664
1733
|
# Returns a new object of the associated type that has been instantiated
|
1665
1734
|
# with +attributes+, linked to this object through a foreign key, and that
|
1666
1735
|
# has already been saved (if it passed the validation).
|
1667
|
-
# [create_association!(attributes = {})]
|
1736
|
+
# [<tt>create_association!(attributes = {})</tt>]
|
1668
1737
|
# Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
|
1669
1738
|
# if the record is invalid.
|
1670
|
-
# [reload_association]
|
1739
|
+
# [<tt>reload_association</tt>]
|
1671
1740
|
# Returns the associated object, forcing a database read.
|
1672
|
-
# [
|
1741
|
+
# [<tt>reset_association</tt>]
|
1742
|
+
# Unloads the associated object. The next access will query it from the database.
|
1743
|
+
# [<tt>association_changed?</tt>]
|
1673
1744
|
# Returns true if a new associate object has been assigned and the next save will update the foreign key.
|
1674
|
-
# [association_previously_changed
|
1745
|
+
# [<tt>association_previously_changed?</tt>]
|
1675
1746
|
# Returns true if the previous save updated the association to reference a new associate object.
|
1676
1747
|
#
|
1677
|
-
#
|
1678
|
-
#
|
1679
|
-
#
|
1680
|
-
#
|
1681
|
-
#
|
1682
|
-
#
|
1683
|
-
#
|
1684
|
-
# * <tt>Post#create_author!</tt> (similar to <tt>post.author = Author.new; post.author.save!; post.author</tt>)
|
1685
|
-
# * <tt>Post#reload_author</tt>
|
1686
|
-
# * <tt>Post#author_changed?</tt>
|
1687
|
-
# * <tt>Post#author_previously_changed?</tt>
|
1688
|
-
# The declaration can also include an +options+ hash to specialize the behavior of the association.
|
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):
|
1689
1755
|
#
|
1690
|
-
#
|
1756
|
+
# post = Post.find(7)
|
1757
|
+
# author = Author.find(19)
|
1758
|
+
#
|
1759
|
+
# post.author # similar to Author.find(post.author_id)
|
1760
|
+
# post.author = author # similar to post.author_id = author.id
|
1761
|
+
# post.build_author # similar to post.author = Author.new
|
1762
|
+
# post.create_author # similar to post.author = Author.new; post.author.save; post.author
|
1763
|
+
# post.create_author! # similar to post.author = Author.new; post.author.save!; post.author
|
1764
|
+
# post.reload_author
|
1765
|
+
# post.reset_author
|
1766
|
+
# post.author_changed?
|
1767
|
+
# post.author_previously_changed?
|
1768
|
+
#
|
1769
|
+
# ==== Scopes
|
1691
1770
|
#
|
1692
1771
|
# You can pass a second argument +scope+ as a callable (i.e. proc or
|
1693
1772
|
# lambda) to retrieve a specific record or customize the generated query
|
@@ -1698,37 +1777,39 @@ module ActiveRecord
|
|
1698
1777
|
# belongs_to :user, -> { joins(:friends) }
|
1699
1778
|
# belongs_to :level, ->(game) { where("game_level > ?", game.current_level) }
|
1700
1779
|
#
|
1701
|
-
#
|
1780
|
+
# ==== Options
|
1702
1781
|
#
|
1703
|
-
#
|
1782
|
+
# The declaration can also include an +options+ hash to specialize the behavior of the association.
|
1783
|
+
#
|
1784
|
+
# [+:class_name+]
|
1704
1785
|
# Specify the class name of the association. Use it only if that name can't be inferred
|
1705
1786
|
# from the association name. So <tt>belongs_to :author</tt> will by default be linked to the Author class, but
|
1706
1787
|
# if the real class name is Person, you'll have to specify it with this option.
|
1707
|
-
# [
|
1788
|
+
# [+:foreign_key+]
|
1708
1789
|
# Specify the foreign key used for the association. By default this is guessed to be the name
|
1709
1790
|
# of the association with an "_id" suffix. So a class that defines a <tt>belongs_to :person</tt>
|
1710
1791
|
# association will use "person_id" as the default <tt>:foreign_key</tt>. Similarly,
|
1711
1792
|
# <tt>belongs_to :favorite_person, class_name: "Person"</tt> will use a foreign key
|
1712
1793
|
# of "favorite_person_id".
|
1713
1794
|
#
|
1714
|
-
#
|
1715
|
-
# a good idea to set the <tt>:inverse_of</tt> option.
|
1716
|
-
# [
|
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+]
|
1717
1798
|
# Specify the column used to store the associated object's type, if this is a polymorphic
|
1718
1799
|
# association. By default this is guessed to be the name of the association with a "_type"
|
1719
1800
|
# suffix. So a class that defines a <tt>belongs_to :taggable, polymorphic: true</tt>
|
1720
1801
|
# association will use "taggable_type" as the default <tt>:foreign_type</tt>.
|
1721
|
-
# [
|
1802
|
+
# [+:primary_key+]
|
1722
1803
|
# Specify the method that returns the primary key of associated object used for the association.
|
1723
1804
|
# By default this is +id+.
|
1724
|
-
# [
|
1805
|
+
# [+:dependent+]
|
1725
1806
|
# If set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to
|
1726
1807
|
# <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method. If set to
|
1727
1808
|
# <tt>:destroy_async</tt>, the associated object is scheduled to be destroyed in a background job.
|
1728
1809
|
# This option should not be specified when #belongs_to is used in conjunction with
|
1729
1810
|
# a #has_many relationship on another class because of the potential to leave
|
1730
1811
|
# orphaned records behind.
|
1731
|
-
# [
|
1812
|
+
# [+:counter_cache+]
|
1732
1813
|
# Caches the number of belonging objects on the associate class through the use of CounterCache::ClassMethods#increment_counter
|
1733
1814
|
# and CounterCache::ClassMethods#decrement_counter. The counter cache is incremented when an object of this
|
1734
1815
|
# class is created and decremented when it's destroyed. This requires that a column
|
@@ -1740,14 +1821,14 @@ module ActiveRecord
|
|
1740
1821
|
# option (e.g., <tt>counter_cache: :my_custom_counter</tt>.)
|
1741
1822
|
# Note: Specifying a counter cache will add it to that model's list of readonly attributes
|
1742
1823
|
# using +attr_readonly+.
|
1743
|
-
# [
|
1824
|
+
# [+:polymorphic+]
|
1744
1825
|
# Specify this association is a polymorphic association by passing +true+.
|
1745
1826
|
# Note: If you've enabled the counter cache, then you may want to add the counter cache attribute
|
1746
1827
|
# to the +attr_readonly+ list in the associated classes (e.g. <tt>class Post; attr_readonly :comments_count; end</tt>).
|
1747
|
-
# [
|
1828
|
+
# [+:validate+]
|
1748
1829
|
# When set to +true+, validates new objects added to association when saving the parent object. +false+ by default.
|
1749
1830
|
# If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
|
1750
|
-
# [
|
1831
|
+
# [+:autosave+]
|
1751
1832
|
# If true, always save the associated object or destroy it if marked for destruction, when
|
1752
1833
|
# saving the parent object.
|
1753
1834
|
# If false, never save or destroy the associated object.
|
@@ -1755,32 +1836,37 @@ module ActiveRecord
|
|
1755
1836
|
#
|
1756
1837
|
# Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for
|
1757
1838
|
# sets <tt>:autosave</tt> to <tt>true</tt>.
|
1758
|
-
# [
|
1839
|
+
# [+:touch+]
|
1759
1840
|
# If true, the associated object will be touched (the +updated_at+ / +updated_on+ attributes set to current time)
|
1760
1841
|
# when this record is either saved or destroyed. If you specify a symbol, that attribute
|
1761
1842
|
# will be updated with the current time in addition to the +updated_at+ / +updated_on+ attribute.
|
1762
1843
|
# Please note that no validation will be performed when touching, and only the +after_touch+,
|
1763
1844
|
# +after_commit+, and +after_rollback+ callbacks will be executed.
|
1764
|
-
# [
|
1845
|
+
# [+:inverse_of+]
|
1765
1846
|
# Specifies the name of the #has_one or #has_many association on the associated
|
1766
1847
|
# object that is the inverse of this #belongs_to association.
|
1767
1848
|
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
|
1768
|
-
# [
|
1849
|
+
# [+:optional+]
|
1769
1850
|
# When set to +true+, the association will not have its presence validated.
|
1770
|
-
# [
|
1851
|
+
# [+:required+]
|
1771
1852
|
# When set to +true+, the association will also have its presence validated.
|
1772
1853
|
# This will validate the association itself, not the id. You can use
|
1773
1854
|
# +:inverse_of+ to avoid an extra query during validation.
|
1774
1855
|
# NOTE: <tt>required</tt> is set to <tt>true</tt> by default and is deprecated. If
|
1775
1856
|
# you don't want to have association presence validated, use <tt>optional: true</tt>.
|
1776
|
-
# [
|
1857
|
+
# [+:default+]
|
1777
1858
|
# Provide a callable (i.e. proc or lambda) to specify that the association should
|
1778
1859
|
# be initialized with a particular record before validation.
|
1779
|
-
#
|
1860
|
+
# Please note that callable won't be executed if the record exists.
|
1861
|
+
# [+:strict_loading+]
|
1780
1862
|
# Enforces strict loading every time the associated record is loaded through this association.
|
1781
|
-
# [
|
1863
|
+
# [+:ensuring_owner_was+]
|
1782
1864
|
# Specifies an instance method to be called on the owner. The method must return true in order for the
|
1783
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.
|
1784
1870
|
#
|
1785
1871
|
# Option examples:
|
1786
1872
|
# belongs_to :firm, foreign_key: "client_of"
|
@@ -1796,6 +1882,7 @@ module ActiveRecord
|
|
1796
1882
|
# belongs_to :user, optional: true
|
1797
1883
|
# belongs_to :account, default: -> { company.account }
|
1798
1884
|
# belongs_to :account, strict_loading: true
|
1885
|
+
# belong_to :note, query_constraints: [:organization_id, :note_id]
|
1799
1886
|
def belongs_to(name, scope = nil, **options)
|
1800
1887
|
reflection = Builder::BelongsTo.build(self, name, scope, options)
|
1801
1888
|
Reflection.add_reflection self, name, reflection
|
@@ -1818,7 +1905,7 @@ module ActiveRecord
|
|
1818
1905
|
# The join table should not have a primary key or a model associated with it. You must manually generate the
|
1819
1906
|
# join table with a migration such as this:
|
1820
1907
|
#
|
1821
|
-
# class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration[7.
|
1908
|
+
# class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration[7.1]
|
1822
1909
|
# def change
|
1823
1910
|
# create_join_table :developers, :projects
|
1824
1911
|
# end
|
@@ -1833,71 +1920,80 @@ module ActiveRecord
|
|
1833
1920
|
# +collection+ is a placeholder for the symbol passed as the +name+ argument, so
|
1834
1921
|
# <tt>has_and_belongs_to_many :categories</tt> would add among others <tt>categories.empty?</tt>.
|
1835
1922
|
#
|
1836
|
-
# [collection]
|
1923
|
+
# [<tt>collection</tt>]
|
1837
1924
|
# Returns a Relation of all the associated objects.
|
1838
1925
|
# An empty Relation is returned if none are found.
|
1839
|
-
# [collection<<(object, ...)]
|
1926
|
+
# [<tt>collection<<(object, ...)</tt>]
|
1840
1927
|
# Adds one or more objects to the collection by creating associations in the join table
|
1841
1928
|
# (<tt>collection.push</tt> and <tt>collection.concat</tt> are aliases to this method).
|
1842
1929
|
# Note that this operation instantly fires update SQL without waiting for the save or update call on the
|
1843
1930
|
# parent object, unless the parent object is a new record.
|
1844
|
-
# [collection.delete(object, ...)]
|
1931
|
+
# [<tt>collection.delete(object, ...)</tt>]
|
1845
1932
|
# Removes one or more objects from the collection by removing their associations from the join table.
|
1846
1933
|
# This does not destroy the objects.
|
1847
|
-
# [collection.destroy(object, ...)]
|
1934
|
+
# [<tt>collection.destroy(object, ...)</tt>]
|
1848
1935
|
# Removes one or more objects from the collection by running destroy on each association in the join table, overriding any dependent option.
|
1849
1936
|
# This does not destroy the objects.
|
1850
|
-
# [collection=objects]
|
1937
|
+
# [<tt>collection=objects</tt>]
|
1851
1938
|
# Replaces the collection's content by deleting and adding objects as appropriate.
|
1852
|
-
# [collection_singular_ids]
|
1939
|
+
# [<tt>collection_singular_ids</tt>]
|
1853
1940
|
# Returns an array of the associated objects' ids.
|
1854
|
-
# [collection_singular_ids=ids]
|
1941
|
+
# [<tt>collection_singular_ids=ids</tt>]
|
1855
1942
|
# Replace the collection by the objects identified by the primary keys in +ids+.
|
1856
|
-
# [collection.clear]
|
1943
|
+
# [<tt>collection.clear</tt>]
|
1857
1944
|
# Removes every object from the collection. This does not destroy the objects.
|
1858
|
-
# [collection.empty
|
1945
|
+
# [<tt>collection.empty?</tt>]
|
1859
1946
|
# Returns +true+ if there are no associated objects.
|
1860
|
-
# [collection.size]
|
1947
|
+
# [<tt>collection.size</tt>]
|
1861
1948
|
# Returns the number of associated objects.
|
1862
|
-
# [collection.find(id)]
|
1949
|
+
# [<tt>collection.find(id)</tt>]
|
1863
1950
|
# Finds an associated object responding to the +id+ and that
|
1864
1951
|
# meets the condition that it has to be associated with this object.
|
1865
1952
|
# Uses the same rules as ActiveRecord::FinderMethods#find.
|
1866
|
-
# [collection.exists?(...)]
|
1953
|
+
# [<tt>collection.exists?(...)</tt>]
|
1867
1954
|
# Checks whether an associated object with the given conditions exists.
|
1868
1955
|
# Uses the same rules as ActiveRecord::FinderMethods#exists?.
|
1869
|
-
# [collection.build(attributes = {})]
|
1956
|
+
# [<tt>collection.build(attributes = {})</tt>]
|
1870
1957
|
# Returns a new object of the collection type that has been instantiated
|
1871
1958
|
# with +attributes+ and linked to this object through the join table, but has not yet been saved.
|
1872
|
-
# [collection.create(attributes = {})]
|
1959
|
+
# [<tt>collection.create(attributes = {})</tt>]
|
1873
1960
|
# Returns a new object of the collection type that has been instantiated
|
1874
1961
|
# with +attributes+, linked to this object through the join table, and that has already been
|
1875
1962
|
# saved (if it passed the validation).
|
1876
|
-
# [collection.reload]
|
1963
|
+
# [<tt>collection.reload</tt>]
|
1877
1964
|
# Returns a Relation of all of the associated objects, forcing a database read.
|
1878
1965
|
# An empty Relation is returned if none are found.
|
1879
1966
|
#
|
1880
|
-
#
|
1881
|
-
#
|
1882
|
-
#
|
1883
|
-
#
|
1884
|
-
#
|
1885
|
-
#
|
1886
|
-
#
|
1887
|
-
#
|
1888
|
-
#
|
1889
|
-
#
|
1890
|
-
#
|
1891
|
-
#
|
1892
|
-
#
|
1893
|
-
#
|
1894
|
-
#
|
1895
|
-
#
|
1896
|
-
#
|
1897
|
-
#
|
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
|
+
#
|
1898
1994
|
# The declaration may include an +options+ hash to specialize the behavior of the association.
|
1899
1995
|
#
|
1900
|
-
#
|
1996
|
+
# ==== Scopes
|
1901
1997
|
#
|
1902
1998
|
# You can pass a second argument +scope+ as a callable (i.e. proc or
|
1903
1999
|
# lambda) to retrieve a specific set of records or customize the generated
|
@@ -1909,7 +2005,7 @@ module ActiveRecord
|
|
1909
2005
|
# where("default_category = ?", post.default_category)
|
1910
2006
|
# }
|
1911
2007
|
#
|
1912
|
-
#
|
2008
|
+
# ==== Extensions
|
1913
2009
|
#
|
1914
2010
|
# The +extension+ argument allows you to pass a block into a
|
1915
2011
|
# has_and_belongs_to_many association. This is useful for adding new
|
@@ -1924,33 +2020,33 @@ module ActiveRecord
|
|
1924
2020
|
# end
|
1925
2021
|
# end
|
1926
2022
|
#
|
1927
|
-
#
|
2023
|
+
# ==== Options
|
1928
2024
|
#
|
1929
|
-
# [
|
2025
|
+
# [+:class_name+]
|
1930
2026
|
# Specify the class name of the association. Use it only if that name can't be inferred
|
1931
2027
|
# from the association name. So <tt>has_and_belongs_to_many :projects</tt> will by default be linked to the
|
1932
2028
|
# Project class, but if the real class name is SuperProject, you'll have to specify it with this option.
|
1933
|
-
# [
|
2029
|
+
# [+:join_table+]
|
1934
2030
|
# Specify the name of the join table if the default based on lexical order isn't what you want.
|
1935
2031
|
# <b>WARNING:</b> If you're overwriting the table name of either class, the +table_name+ method
|
1936
2032
|
# MUST be declared underneath any #has_and_belongs_to_many declaration in order to work.
|
1937
|
-
# [
|
2033
|
+
# [+:foreign_key+]
|
1938
2034
|
# Specify the foreign key used for the association. By default this is guessed to be the name
|
1939
2035
|
# of this class in lower-case and "_id" suffixed. So a Person class that makes
|
1940
2036
|
# a #has_and_belongs_to_many association to Project will use "person_id" as the
|
1941
2037
|
# default <tt>:foreign_key</tt>.
|
1942
2038
|
#
|
1943
|
-
#
|
1944
|
-
# a good idea to set the <tt>:inverse_of</tt> option.
|
1945
|
-
# [
|
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+]
|
1946
2042
|
# Specify the foreign key used for the association on the receiving side of the association.
|
1947
2043
|
# By default this is guessed to be the name of the associated class in lower-case and "_id" suffixed.
|
1948
2044
|
# So if a Person class makes a #has_and_belongs_to_many association to Project,
|
1949
2045
|
# the association will use "project_id" as the default <tt>:association_foreign_key</tt>.
|
1950
|
-
# [
|
2046
|
+
# [+:validate+]
|
1951
2047
|
# When set to +true+, validates new objects added to association when saving the parent object. +true+ by default.
|
1952
2048
|
# If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
|
1953
|
-
# [
|
2049
|
+
# [+:autosave+]
|
1954
2050
|
# If true, always save the associated objects or destroy them if marked for destruction, when
|
1955
2051
|
# saving the parent object.
|
1956
2052
|
# If false, never save or destroy the associated objects.
|
@@ -1958,7 +2054,7 @@ module ActiveRecord
|
|
1958
2054
|
#
|
1959
2055
|
# Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
|
1960
2056
|
# <tt>:autosave</tt> to <tt>true</tt>.
|
1961
|
-
# [
|
2057
|
+
# [+:strict_loading+]
|
1962
2058
|
# Enforces strict loading every time an associated record is loaded through this association.
|
1963
2059
|
#
|
1964
2060
|
# Option examples:
|