activerecord 4.2.0 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1537 -789
- data/MIT-LICENSE +2 -2
- data/README.rdoc +7 -8
- data/examples/performance.rb +2 -3
- data/examples/simple.rb +0 -1
- data/lib/active_record/aggregations.rb +37 -23
- data/lib/active_record/association_relation.rb +16 -3
- data/lib/active_record/associations/alias_tracker.rb +19 -16
- data/lib/active_record/associations/association.rb +23 -9
- data/lib/active_record/associations/association_scope.rb +74 -102
- data/lib/active_record/associations/belongs_to_association.rb +26 -29
- data/lib/active_record/associations/builder/association.rb +28 -34
- data/lib/active_record/associations/builder/belongs_to.rb +43 -18
- data/lib/active_record/associations/builder/collection_association.rb +12 -20
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +22 -15
- data/lib/active_record/associations/builder/has_many.rb +4 -4
- data/lib/active_record/associations/builder/has_one.rb +11 -6
- data/lib/active_record/associations/builder/singular_association.rb +3 -10
- data/lib/active_record/associations/collection_association.rb +61 -33
- data/lib/active_record/associations/collection_proxy.rb +81 -35
- data/lib/active_record/associations/foreign_association.rb +11 -0
- data/lib/active_record/associations/has_many_association.rb +21 -57
- data/lib/active_record/associations/has_many_through_association.rb +15 -45
- data/lib/active_record/associations/has_one_association.rb +13 -5
- data/lib/active_record/associations/join_dependency/join_association.rb +20 -8
- data/lib/active_record/associations/join_dependency.rb +37 -21
- data/lib/active_record/associations/preloader/association.rb +51 -53
- data/lib/active_record/associations/preloader/collection_association.rb +0 -6
- data/lib/active_record/associations/preloader/has_many_through.rb +1 -1
- data/lib/active_record/associations/preloader/has_one.rb +0 -8
- data/lib/active_record/associations/preloader/through_association.rb +27 -14
- data/lib/active_record/associations/preloader.rb +18 -8
- data/lib/active_record/associations/singular_association.rb +8 -8
- data/lib/active_record/associations/through_association.rb +22 -9
- data/lib/active_record/associations.rb +321 -212
- data/lib/active_record/attribute/user_provided_default.rb +28 -0
- data/lib/active_record/attribute.rb +79 -15
- data/lib/active_record/attribute_assignment.rb +20 -141
- data/lib/active_record/attribute_decorators.rb +6 -5
- data/lib/active_record/attribute_methods/before_type_cast.rb +6 -1
- data/lib/active_record/attribute_methods/dirty.rb +51 -81
- data/lib/active_record/attribute_methods/primary_key.rb +2 -2
- data/lib/active_record/attribute_methods/query.rb +2 -2
- data/lib/active_record/attribute_methods/read.rb +31 -59
- data/lib/active_record/attribute_methods/serialization.rb +13 -16
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +65 -14
- data/lib/active_record/attribute_methods/write.rb +14 -38
- data/lib/active_record/attribute_methods.rb +70 -45
- data/lib/active_record/attribute_mutation_tracker.rb +70 -0
- data/lib/active_record/attribute_set/builder.rb +37 -15
- data/lib/active_record/attribute_set.rb +34 -3
- data/lib/active_record/attributes.rb +199 -73
- data/lib/active_record/autosave_association.rb +73 -25
- data/lib/active_record/base.rb +35 -27
- data/lib/active_record/callbacks.rb +39 -43
- data/lib/active_record/coders/json.rb +1 -1
- data/lib/active_record/coders/yaml_column.rb +20 -8
- data/lib/active_record/collection_cache_key.rb +40 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +457 -181
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +83 -59
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/quoting.rb +74 -9
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -4
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +61 -39
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +246 -185
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +72 -17
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +438 -136
- data/lib/active_record/connection_adapters/abstract/transaction.rb +53 -40
- data/lib/active_record/connection_adapters/abstract_adapter.rb +166 -66
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +429 -335
- data/lib/active_record/connection_adapters/column.rb +28 -43
- data/lib/active_record/connection_adapters/connection_specification.rb +15 -27
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +22 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +50 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +125 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +70 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +51 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +67 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +93 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +32 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -177
- data/lib/active_record/connection_adapters/postgresql/column.rb +5 -10
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +11 -73
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +42 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +27 -56
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -1
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +7 -13
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +3 -3
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +1 -26
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +0 -4
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +31 -17
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +17 -5
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid.rb +1 -6
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +26 -18
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +29 -10
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -79
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +47 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +248 -154
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +35 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +258 -170
- data/lib/active_record/connection_adapters/schema_cache.rb +36 -23
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +32 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +48 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +150 -209
- data/lib/active_record/connection_adapters/statement_pool.rb +31 -12
- data/lib/active_record/connection_handling.rb +38 -15
- data/lib/active_record/core.rb +109 -114
- data/lib/active_record/counter_cache.rb +14 -25
- data/lib/active_record/dynamic_matchers.rb +1 -20
- data/lib/active_record/enum.rb +115 -79
- data/lib/active_record/errors.rb +88 -48
- data/lib/active_record/explain_registry.rb +1 -1
- data/lib/active_record/explain_subscriber.rb +2 -2
- data/lib/active_record/fixture_set/file.rb +26 -5
- data/lib/active_record/fixtures.rb +84 -46
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/inheritance.rb +32 -40
- data/lib/active_record/integration.rb +4 -4
- data/lib/active_record/internal_metadata.rb +56 -0
- data/lib/active_record/legacy_yaml_adapter.rb +46 -0
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +27 -25
- data/lib/active_record/locking/pessimistic.rb +1 -1
- data/lib/active_record/log_subscriber.rb +43 -21
- data/lib/active_record/migration/command_recorder.rb +59 -18
- data/lib/active_record/migration/compatibility.rb +126 -0
- data/lib/active_record/migration.rb +372 -114
- data/lib/active_record/model_schema.rb +128 -38
- data/lib/active_record/nested_attributes.rb +71 -32
- data/lib/active_record/no_touching.rb +1 -1
- data/lib/active_record/null_relation.rb +16 -8
- data/lib/active_record/persistence.rb +124 -80
- data/lib/active_record/query_cache.rb +15 -18
- data/lib/active_record/querying.rb +10 -9
- data/lib/active_record/railtie.rb +28 -19
- data/lib/active_record/railties/controller_runtime.rb +1 -1
- data/lib/active_record/railties/databases.rake +67 -51
- data/lib/active_record/readonly_attributes.rb +1 -1
- data/lib/active_record/reflection.rb +318 -139
- data/lib/active_record/relation/batches/batch_enumerator.rb +67 -0
- data/lib/active_record/relation/batches.rb +139 -34
- data/lib/active_record/relation/calculations.rb +80 -102
- data/lib/active_record/relation/delegation.rb +7 -20
- data/lib/active_record/relation/finder_methods.rb +167 -97
- data/lib/active_record/relation/from_clause.rb +32 -0
- data/lib/active_record/relation/merger.rb +38 -41
- data/lib/active_record/relation/predicate_builder/array_handler.rb +12 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +88 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +17 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +17 -0
- data/lib/active_record/relation/predicate_builder/class_handler.rb +27 -0
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +57 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +33 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/predicate_builder.rb +124 -82
- data/lib/active_record/relation/query_attribute.rb +19 -0
- data/lib/active_record/relation/query_methods.rb +323 -257
- data/lib/active_record/relation/record_fetch_warning.rb +49 -0
- data/lib/active_record/relation/spawn_methods.rb +11 -10
- data/lib/active_record/relation/where_clause.rb +174 -0
- data/lib/active_record/relation/where_clause_factory.rb +38 -0
- data/lib/active_record/relation.rb +176 -115
- data/lib/active_record/result.rb +4 -3
- data/lib/active_record/runtime_registry.rb +1 -1
- data/lib/active_record/sanitization.rb +95 -66
- data/lib/active_record/schema.rb +26 -22
- data/lib/active_record/schema_dumper.rb +62 -38
- data/lib/active_record/schema_migration.rb +11 -17
- data/lib/active_record/scoping/default.rb +24 -9
- data/lib/active_record/scoping/named.rb +49 -28
- data/lib/active_record/scoping.rb +32 -15
- data/lib/active_record/secure_token.rb +38 -0
- data/lib/active_record/serialization.rb +2 -4
- data/lib/active_record/statement_cache.rb +16 -14
- data/lib/active_record/store.rb +8 -3
- data/lib/active_record/suppressor.rb +58 -0
- data/lib/active_record/table_metadata.rb +68 -0
- data/lib/active_record/tasks/database_tasks.rb +59 -42
- data/lib/active_record/tasks/mysql_database_tasks.rb +32 -26
- data/lib/active_record/tasks/postgresql_database_tasks.rb +29 -9
- data/lib/active_record/tasks/sqlite_database_tasks.rb +5 -1
- data/lib/active_record/timestamp.rb +20 -9
- data/lib/active_record/touch_later.rb +58 -0
- data/lib/active_record/transactions.rb +159 -67
- data/lib/active_record/type/adapter_specific_registry.rb +130 -0
- data/lib/active_record/type/date.rb +2 -41
- data/lib/active_record/type/date_time.rb +2 -38
- data/lib/active_record/type/hash_lookup_type_map.rb +8 -2
- data/lib/active_record/type/internal/abstract_json.rb +29 -0
- data/lib/active_record/type/internal/timezone.rb +15 -0
- data/lib/active_record/type/serialized.rb +21 -14
- data/lib/active_record/type/time.rb +10 -16
- data/lib/active_record/type/type_map.rb +4 -4
- data/lib/active_record/type.rb +66 -17
- data/lib/active_record/type_caster/connection.rb +29 -0
- data/lib/active_record/type_caster/map.rb +19 -0
- data/lib/active_record/type_caster.rb +7 -0
- data/lib/active_record/validations/absence.rb +23 -0
- data/lib/active_record/validations/associated.rb +10 -3
- data/lib/active_record/validations/length.rb +24 -0
- data/lib/active_record/validations/presence.rb +11 -12
- data/lib/active_record/validations/uniqueness.rb +29 -18
- data/lib/active_record/validations.rb +33 -32
- data/lib/active_record.rb +9 -2
- data/lib/rails/generators/active_record/migration/migration_generator.rb +7 -4
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +8 -6
- data/lib/rails/generators/active_record/migration/templates/migration.rb +8 -7
- data/lib/rails/generators/active_record/migration.rb +7 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +32 -15
- data/lib/rails/generators/active_record/model/templates/application_record.rb +5 -0
- data/lib/rails/generators/active_record/model/templates/model.rb +3 -0
- metadata +60 -34
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
- data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +0 -11
- data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
- data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
- data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
- data/lib/active_record/serializers/xml_serializer.rb +0 -193
- data/lib/active_record/type/big_integer.rb +0 -13
- data/lib/active_record/type/binary.rb +0 -50
- data/lib/active_record/type/boolean.rb +0 -30
- data/lib/active_record/type/decimal.rb +0 -40
- data/lib/active_record/type/decimal_without_scale.rb +0 -11
- data/lib/active_record/type/decorator.rb +0 -14
- data/lib/active_record/type/float.rb +0 -19
- data/lib/active_record/type/integer.rb +0 -55
- data/lib/active_record/type/mutable.rb +0 -16
- data/lib/active_record/type/numeric.rb +0 -36
- data/lib/active_record/type/string.rb +0 -36
- data/lib/active_record/type/text.rb +0 -11
- data/lib/active_record/type/time_value.rb +0 -38
- data/lib/active_record/type/unsigned_integer.rb +0 -15
- data/lib/active_record/type/value.rb +0 -101
@@ -5,95 +5,170 @@ require 'active_record/errors'
|
|
5
5
|
|
6
6
|
module ActiveRecord
|
7
7
|
class AssociationNotFoundError < ConfigurationError #:nodoc:
|
8
|
-
def initialize(record, association_name)
|
9
|
-
|
8
|
+
def initialize(record = nil, association_name = nil)
|
9
|
+
if record && association_name
|
10
|
+
super("Association named '#{association_name}' was not found on #{record.class.name}; perhaps you misspelled it?")
|
11
|
+
else
|
12
|
+
super("Association was not found.")
|
13
|
+
end
|
10
14
|
end
|
11
15
|
end
|
12
16
|
|
13
17
|
class InverseOfAssociationNotFoundError < ActiveRecordError #:nodoc:
|
14
|
-
def initialize(reflection, associated_class = nil)
|
15
|
-
|
18
|
+
def initialize(reflection = nil, associated_class = nil)
|
19
|
+
if reflection
|
20
|
+
super("Could not find the inverse association for #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{associated_class.nil? ? reflection.class_name : associated_class.name})")
|
21
|
+
else
|
22
|
+
super("Could not find the inverse association.")
|
23
|
+
end
|
16
24
|
end
|
17
25
|
end
|
18
26
|
|
19
27
|
class HasManyThroughAssociationNotFoundError < ActiveRecordError #:nodoc:
|
20
|
-
def initialize(owner_class_name, reflection)
|
21
|
-
|
28
|
+
def initialize(owner_class_name = nil, reflection = nil)
|
29
|
+
if owner_class_name && reflection
|
30
|
+
super("Could not find the association #{reflection.options[:through].inspect} in model #{owner_class_name}")
|
31
|
+
else
|
32
|
+
super("Could not find the association.")
|
33
|
+
end
|
22
34
|
end
|
23
35
|
end
|
24
36
|
|
25
37
|
class HasManyThroughAssociationPolymorphicSourceError < ActiveRecordError #:nodoc:
|
26
|
-
def initialize(owner_class_name, reflection, source_reflection)
|
27
|
-
|
38
|
+
def initialize(owner_class_name = nil, reflection = nil, source_reflection = nil)
|
39
|
+
if owner_class_name && reflection && source_reflection
|
40
|
+
super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' on the polymorphic object '#{source_reflection.class_name}##{source_reflection.name}' without 'source_type'. Try adding 'source_type: \"#{reflection.name.to_s.classify}\"' to 'has_many :through' definition.")
|
41
|
+
else
|
42
|
+
super("Cannot have a has_many :through association.")
|
43
|
+
end
|
28
44
|
end
|
29
45
|
end
|
30
46
|
|
31
47
|
class HasManyThroughAssociationPolymorphicThroughError < ActiveRecordError #:nodoc:
|
32
|
-
def initialize(owner_class_name, reflection)
|
33
|
-
|
48
|
+
def initialize(owner_class_name = nil, reflection = nil)
|
49
|
+
if owner_class_name && reflection
|
50
|
+
super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' which goes through the polymorphic association '#{owner_class_name}##{reflection.through_reflection.name}'.")
|
51
|
+
else
|
52
|
+
super("Cannot have a has_many :through association.")
|
53
|
+
end
|
34
54
|
end
|
35
55
|
end
|
36
56
|
|
37
57
|
class HasManyThroughAssociationPointlessSourceTypeError < ActiveRecordError #:nodoc:
|
38
|
-
def initialize(owner_class_name, reflection, source_reflection)
|
39
|
-
|
58
|
+
def initialize(owner_class_name = nil, reflection = nil, source_reflection = nil)
|
59
|
+
if owner_class_name && reflection && source_reflection
|
60
|
+
super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' with a :source_type option if the '#{reflection.through_reflection.class_name}##{source_reflection.name}' is not polymorphic. Try removing :source_type on your association.")
|
61
|
+
else
|
62
|
+
super("Cannot have a has_many :through association.")
|
63
|
+
end
|
40
64
|
end
|
41
65
|
end
|
42
66
|
|
43
67
|
class HasOneThroughCantAssociateThroughCollection < ActiveRecordError #:nodoc:
|
44
|
-
def initialize(owner_class_name, reflection, through_reflection)
|
45
|
-
|
68
|
+
def initialize(owner_class_name = nil, reflection = nil, through_reflection = nil)
|
69
|
+
if owner_class_name && reflection && through_reflection
|
70
|
+
super("Cannot have a has_one :through association '#{owner_class_name}##{reflection.name}' where the :through association '#{owner_class_name}##{through_reflection.name}' is a collection. Specify a has_one or belongs_to association in the :through option instead.")
|
71
|
+
else
|
72
|
+
super("Cannot have a has_one :through association.")
|
73
|
+
end
|
46
74
|
end
|
47
75
|
end
|
48
76
|
|
49
77
|
class HasOneAssociationPolymorphicThroughError < ActiveRecordError #:nodoc:
|
50
|
-
def initialize(owner_class_name, reflection)
|
51
|
-
|
78
|
+
def initialize(owner_class_name = nil, reflection = nil)
|
79
|
+
if owner_class_name && reflection
|
80
|
+
super("Cannot have a has_one :through association '#{owner_class_name}##{reflection.name}' which goes through the polymorphic association '#{owner_class_name}##{reflection.through_reflection.name}'.")
|
81
|
+
else
|
82
|
+
super("Cannot have a has_one :through association.")
|
83
|
+
end
|
52
84
|
end
|
53
85
|
end
|
54
86
|
|
55
87
|
class HasManyThroughSourceAssociationNotFoundError < ActiveRecordError #:nodoc:
|
56
|
-
def initialize(reflection)
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
88
|
+
def initialize(reflection = nil)
|
89
|
+
if reflection
|
90
|
+
through_reflection = reflection.through_reflection
|
91
|
+
source_reflection_names = reflection.source_reflection_names
|
92
|
+
source_associations = reflection.through_reflection.klass._reflections.keys
|
93
|
+
super("Could not find the source association(s) #{source_reflection_names.collect(&:inspect).to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)} in model #{through_reflection.klass}. Try 'has_many #{reflection.name.inspect}, :through => #{through_reflection.name.inspect}, :source => <name>'. Is it one of #{source_associations.to_sentence(:two_words_connector => ' or ', :last_word_connector => ', or ', :locale => :en)}?")
|
94
|
+
else
|
95
|
+
super("Could not find the source association(s).")
|
96
|
+
end
|
61
97
|
end
|
62
98
|
end
|
63
99
|
|
64
|
-
class
|
65
|
-
def initialize(owner, reflection)
|
66
|
-
|
100
|
+
class ThroughCantAssociateThroughHasOneOrManyReflection < ActiveRecordError #:nodoc:
|
101
|
+
def initialize(owner = nil, reflection = nil)
|
102
|
+
if owner && reflection
|
103
|
+
super("Cannot modify association '#{owner.class.name}##{reflection.name}' because the source reflection class '#{reflection.source_reflection.class_name}' is associated to '#{reflection.through_reflection.class_name}' via :#{reflection.source_reflection.macro}.")
|
104
|
+
else
|
105
|
+
super("Cannot modify association.")
|
106
|
+
end
|
67
107
|
end
|
68
108
|
end
|
69
109
|
|
110
|
+
class HasManyThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection #:nodoc:
|
111
|
+
end
|
112
|
+
|
113
|
+
class HasOneThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection #:nodoc:
|
114
|
+
end
|
115
|
+
|
70
116
|
class HasManyThroughCantAssociateNewRecords < ActiveRecordError #:nodoc:
|
71
|
-
def initialize(owner, reflection)
|
72
|
-
|
117
|
+
def initialize(owner = nil, reflection = nil)
|
118
|
+
if owner && reflection
|
119
|
+
super("Cannot associate new records through '#{owner.class.name}##{reflection.name}' on '#{reflection.source_reflection.class_name rescue nil}##{reflection.source_reflection.name rescue nil}'. Both records must have an id in order to create the has_many :through record associating them.")
|
120
|
+
else
|
121
|
+
super("Cannot associate new records.")
|
122
|
+
end
|
73
123
|
end
|
74
124
|
end
|
75
125
|
|
76
126
|
class HasManyThroughCantDissociateNewRecords < ActiveRecordError #:nodoc:
|
77
|
-
def initialize(owner, reflection)
|
78
|
-
|
127
|
+
def initialize(owner = nil, reflection = nil)
|
128
|
+
if owner && reflection
|
129
|
+
super("Cannot dissociate new records through '#{owner.class.name}##{reflection.name}' on '#{reflection.source_reflection.class_name rescue nil}##{reflection.source_reflection.name rescue nil}'. Both records must have an id in order to delete the has_many :through record associating them.")
|
130
|
+
else
|
131
|
+
super("Cannot dissociate new records.")
|
132
|
+
end
|
79
133
|
end
|
80
134
|
end
|
81
135
|
|
82
|
-
class
|
83
|
-
def initialize(owner, reflection)
|
84
|
-
|
136
|
+
class ThroughNestedAssociationsAreReadonly < ActiveRecordError #:nodoc:
|
137
|
+
def initialize(owner = nil, reflection = nil)
|
138
|
+
if owner && reflection
|
139
|
+
super("Cannot modify association '#{owner.class.name}##{reflection.name}' because it goes through more than one other association.")
|
140
|
+
else
|
141
|
+
super("Through nested associations are read-only.")
|
142
|
+
end
|
85
143
|
end
|
86
144
|
end
|
87
145
|
|
88
|
-
class
|
89
|
-
|
90
|
-
|
146
|
+
class HasManyThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly #:nodoc:
|
147
|
+
end
|
148
|
+
|
149
|
+
class HasOneThroughNestedAssociationsAreReadonly < ThroughNestedAssociationsAreReadonly #:nodoc:
|
150
|
+
end
|
151
|
+
|
152
|
+
# This error is raised when trying to eager load a polymorphic association using a JOIN.
|
153
|
+
# Eager loading polymorphic associations is only possible with
|
154
|
+
# {ActiveRecord::Relation#preload}[rdoc-ref:QueryMethods#preload].
|
155
|
+
class EagerLoadPolymorphicError < ActiveRecordError
|
156
|
+
def initialize(reflection = nil)
|
157
|
+
if reflection
|
158
|
+
super("Cannot eagerly load the polymorphic association #{reflection.name.inspect}")
|
159
|
+
else
|
160
|
+
super("Eager load polymorphic error.")
|
161
|
+
end
|
91
162
|
end
|
92
163
|
end
|
93
164
|
|
94
165
|
class ReadOnlyAssociation < ActiveRecordError #:nodoc:
|
95
|
-
def initialize(reflection)
|
96
|
-
|
166
|
+
def initialize(reflection = nil)
|
167
|
+
if reflection
|
168
|
+
super("Cannot add to a has_many :through association. Try adding to #{reflection.through_reflection.name.inspect}.")
|
169
|
+
else
|
170
|
+
super("Read-only reflection error.")
|
171
|
+
end
|
97
172
|
end
|
98
173
|
end
|
99
174
|
|
@@ -101,8 +176,12 @@ module ActiveRecord
|
|
101
176
|
# (has_many, has_one) when there is at least 1 child associated instance.
|
102
177
|
# ex: if @project.tasks.size > 0, DeleteRestrictionError will be raised when trying to destroy @project
|
103
178
|
class DeleteRestrictionError < ActiveRecordError #:nodoc:
|
104
|
-
def initialize(name)
|
105
|
-
|
179
|
+
def initialize(name = nil)
|
180
|
+
if name
|
181
|
+
super("Cannot delete record because of dependent #{name}")
|
182
|
+
else
|
183
|
+
super("Delete restriction error.")
|
184
|
+
end
|
106
185
|
end
|
107
186
|
end
|
108
187
|
|
@@ -113,18 +192,19 @@ module ActiveRecord
|
|
113
192
|
|
114
193
|
# These classes will be loaded when associations are created.
|
115
194
|
# So there is no need to eager load them.
|
116
|
-
autoload :Association
|
117
|
-
autoload :SingularAssociation
|
118
|
-
autoload :CollectionAssociation
|
119
|
-
autoload :
|
195
|
+
autoload :Association
|
196
|
+
autoload :SingularAssociation
|
197
|
+
autoload :CollectionAssociation
|
198
|
+
autoload :ForeignAssociation
|
199
|
+
autoload :CollectionProxy
|
120
200
|
|
121
|
-
autoload :BelongsToAssociation
|
122
|
-
autoload :BelongsToPolymorphicAssociation
|
123
|
-
autoload :HasManyAssociation
|
124
|
-
autoload :HasManyThroughAssociation
|
125
|
-
autoload :HasOneAssociation
|
126
|
-
autoload :HasOneThroughAssociation
|
127
|
-
autoload :ThroughAssociation
|
201
|
+
autoload :BelongsToAssociation
|
202
|
+
autoload :BelongsToPolymorphicAssociation
|
203
|
+
autoload :HasManyAssociation
|
204
|
+
autoload :HasManyThroughAssociation
|
205
|
+
autoload :HasOneAssociation
|
206
|
+
autoload :HasOneThroughAssociation
|
207
|
+
autoload :ThroughAssociation
|
128
208
|
|
129
209
|
module Builder #:nodoc:
|
130
210
|
autoload :Association, 'active_record/associations/builder/association'
|
@@ -138,26 +218,20 @@ module ActiveRecord
|
|
138
218
|
end
|
139
219
|
|
140
220
|
eager_autoload do
|
141
|
-
autoload :Preloader
|
142
|
-
autoload :JoinDependency
|
143
|
-
autoload :AssociationScope
|
144
|
-
autoload :AliasTracker
|
145
|
-
end
|
146
|
-
|
147
|
-
# Clears out the association cache.
|
148
|
-
def clear_association_cache #:nodoc:
|
149
|
-
@association_cache.clear if persisted?
|
221
|
+
autoload :Preloader
|
222
|
+
autoload :JoinDependency
|
223
|
+
autoload :AssociationScope
|
224
|
+
autoload :AliasTracker
|
150
225
|
end
|
151
226
|
|
152
|
-
# :nodoc:
|
153
|
-
attr_reader :association_cache
|
154
|
-
|
155
227
|
# Returns the association instance for the given name, instantiating it if it doesn't already exist
|
156
228
|
def association(name) #:nodoc:
|
157
229
|
association = association_instance_get(name)
|
158
230
|
|
159
231
|
if association.nil?
|
160
|
-
|
232
|
+
unless reflection = self.class._reflect_on_association(name)
|
233
|
+
raise AssociationNotFoundError.new(self, name)
|
234
|
+
end
|
161
235
|
association = reflection.association_class.new(self, reflection)
|
162
236
|
association_instance_set(name, association)
|
163
237
|
end
|
@@ -165,8 +239,32 @@ module ActiveRecord
|
|
165
239
|
association
|
166
240
|
end
|
167
241
|
|
242
|
+
def association_cached?(name) # :nodoc
|
243
|
+
@association_cache.key?(name)
|
244
|
+
end
|
245
|
+
|
246
|
+
def initialize_dup(*) # :nodoc:
|
247
|
+
@association_cache = {}
|
248
|
+
super
|
249
|
+
end
|
250
|
+
|
251
|
+
def reload(*) # :nodoc:
|
252
|
+
clear_association_cache
|
253
|
+
super
|
254
|
+
end
|
255
|
+
|
168
256
|
private
|
169
|
-
#
|
257
|
+
# Clears out the association cache.
|
258
|
+
def clear_association_cache # :nodoc:
|
259
|
+
@association_cache.clear if persisted?
|
260
|
+
end
|
261
|
+
|
262
|
+
def init_internals # :nodoc:
|
263
|
+
@association_cache = {}
|
264
|
+
super
|
265
|
+
end
|
266
|
+
|
267
|
+
# Returns the specified association instance if it exists, nil otherwise.
|
170
268
|
def association_instance_get(name)
|
171
269
|
@association_cache[name]
|
172
270
|
end
|
@@ -203,7 +301,7 @@ module ActiveRecord
|
|
203
301
|
# === A word of warning
|
204
302
|
#
|
205
303
|
# Don't create associations that have the same name as instance methods of
|
206
|
-
#
|
304
|
+
# ActiveRecord::Base. Since the association adds a method with that name to
|
207
305
|
# its model, it will override the inherited method and break things.
|
208
306
|
# For instance, +attributes+ and +connection+ would be bad choices for association names.
|
209
307
|
#
|
@@ -220,7 +318,7 @@ module ActiveRecord
|
|
220
318
|
# create_other(attributes={}) | X | | X
|
221
319
|
# create_other!(attributes={}) | X | | X
|
222
320
|
#
|
223
|
-
# ===Collection associations (one-to-many / many-to-many)
|
321
|
+
# === Collection associations (one-to-many / many-to-many)
|
224
322
|
# | | | has_many
|
225
323
|
# generated methods | habtm | has_many | :through
|
226
324
|
# ----------------------------------+-------+----------+----------
|
@@ -247,7 +345,6 @@ module ActiveRecord
|
|
247
345
|
# others.find(*args) | X | X | X
|
248
346
|
# others.exists? | X | X | X
|
249
347
|
# others.distinct | X | X | X
|
250
|
-
# others.uniq | X | X | X
|
251
348
|
# others.reset | X | X | X
|
252
349
|
#
|
253
350
|
# === Overriding generated methods
|
@@ -266,7 +363,7 @@ module ActiveRecord
|
|
266
363
|
# end
|
267
364
|
#
|
268
365
|
# If your model class is <tt>Project</tt>, the module is
|
269
|
-
# named <tt>Project::
|
366
|
+
# named <tt>Project::GeneratedAssociationMethods</tt>. The +GeneratedAssociationMethods+ module is
|
270
367
|
# included in the model class immediately after the (anonymous) generated attributes methods
|
271
368
|
# module, meaning an association will override the methods for an attribute with the same name.
|
272
369
|
#
|
@@ -274,12 +371,12 @@ module ActiveRecord
|
|
274
371
|
#
|
275
372
|
# Active Record associations can be used to describe one-to-one, one-to-many and many-to-many
|
276
373
|
# relationships between models. Each model uses an association to describe its role in
|
277
|
-
# the relation. The
|
374
|
+
# the relation. The #belongs_to association is always used in the model that has
|
278
375
|
# the foreign key.
|
279
376
|
#
|
280
377
|
# === One-to-one
|
281
378
|
#
|
282
|
-
# Use
|
379
|
+
# Use #has_one in the base, and #belongs_to in the associated model.
|
283
380
|
#
|
284
381
|
# class Employee < ActiveRecord::Base
|
285
382
|
# has_one :office
|
@@ -290,7 +387,7 @@ module ActiveRecord
|
|
290
387
|
#
|
291
388
|
# === One-to-many
|
292
389
|
#
|
293
|
-
# Use
|
390
|
+
# Use #has_many in the base, and #belongs_to in the associated model.
|
294
391
|
#
|
295
392
|
# class Manager < ActiveRecord::Base
|
296
393
|
# has_many :employees
|
@@ -303,7 +400,7 @@ module ActiveRecord
|
|
303
400
|
#
|
304
401
|
# There are two ways to build a many-to-many relationship.
|
305
402
|
#
|
306
|
-
# The first way uses a
|
403
|
+
# The first way uses a #has_many association with the <tt>:through</tt> option and a join model, so
|
307
404
|
# there are two stages of associations.
|
308
405
|
#
|
309
406
|
# class Assignment < ActiveRecord::Base
|
@@ -319,7 +416,7 @@ module ActiveRecord
|
|
319
416
|
# has_many :programmers, through: :assignments
|
320
417
|
# end
|
321
418
|
#
|
322
|
-
# For the second way, use
|
419
|
+
# For the second way, use #has_and_belongs_to_many in both models. This requires a join table
|
323
420
|
# that has no corresponding model or primary key.
|
324
421
|
#
|
325
422
|
# class Programmer < ActiveRecord::Base
|
@@ -331,13 +428,13 @@ module ActiveRecord
|
|
331
428
|
#
|
332
429
|
# Choosing which way to build a many-to-many relationship is not always simple.
|
333
430
|
# If you need to work with the relationship model as its own entity,
|
334
|
-
# use <tt
|
431
|
+
# use #has_many <tt>:through</tt>. Use #has_and_belongs_to_many when working with legacy schemas or when
|
335
432
|
# you never work directly with the relationship itself.
|
336
433
|
#
|
337
|
-
# == Is it a
|
434
|
+
# == Is it a #belongs_to or #has_one association?
|
338
435
|
#
|
339
436
|
# Both express a 1-1 relationship. The difference is mostly where to place the foreign
|
340
|
-
# key, which goes on the table for the class declaring the
|
437
|
+
# key, which goes on the table for the class declaring the #belongs_to relationship.
|
341
438
|
#
|
342
439
|
# class User < ActiveRecord::Base
|
343
440
|
# # I reference an account.
|
@@ -352,14 +449,14 @@ module ActiveRecord
|
|
352
449
|
# The tables for these classes could look something like:
|
353
450
|
#
|
354
451
|
# CREATE TABLE users (
|
355
|
-
# id int
|
356
|
-
# account_id int
|
452
|
+
# id int NOT NULL auto_increment,
|
453
|
+
# account_id int default NULL,
|
357
454
|
# name varchar default NULL,
|
358
455
|
# PRIMARY KEY (id)
|
359
456
|
# )
|
360
457
|
#
|
361
458
|
# CREATE TABLE accounts (
|
362
|
-
# id int
|
459
|
+
# id int NOT NULL auto_increment,
|
363
460
|
# name varchar default NULL,
|
364
461
|
# PRIMARY KEY (id)
|
365
462
|
# )
|
@@ -370,35 +467,35 @@ module ActiveRecord
|
|
370
467
|
# there is some special behavior you should be aware of, mostly involving the saving of
|
371
468
|
# associated objects.
|
372
469
|
#
|
373
|
-
# You can set the <tt>:autosave</tt> option on a
|
374
|
-
#
|
470
|
+
# You can set the <tt>:autosave</tt> option on a #has_one, #belongs_to,
|
471
|
+
# #has_many, or #has_and_belongs_to_many association. Setting it
|
375
472
|
# to +true+ will _always_ save the members, whereas setting it to +false+ will
|
376
473
|
# _never_ save the members. More details about <tt>:autosave</tt> option is available at
|
377
474
|
# AutosaveAssociation.
|
378
475
|
#
|
379
476
|
# === One-to-one associations
|
380
477
|
#
|
381
|
-
# * Assigning an object to a
|
478
|
+
# * Assigning an object to a #has_one association automatically saves that object and
|
382
479
|
# the object being replaced (if there is one), in order to update their foreign
|
383
480
|
# keys - except if the parent object is unsaved (<tt>new_record? == true</tt>).
|
384
481
|
# * If either of these saves fail (due to one of the objects being invalid), an
|
385
|
-
#
|
482
|
+
# ActiveRecord::RecordNotSaved exception is raised and the assignment is
|
386
483
|
# cancelled.
|
387
|
-
# * If you wish to assign an object to a
|
388
|
-
# use the <tt
|
484
|
+
# * If you wish to assign an object to a #has_one association without saving it,
|
485
|
+
# use the <tt>#build_association</tt> method (documented below). The object being
|
389
486
|
# replaced will still be saved to update its foreign key.
|
390
|
-
# * Assigning an object to a
|
487
|
+
# * Assigning an object to a #belongs_to association does not save the object, since
|
391
488
|
# the foreign key field belongs on the parent. It does not save the parent either.
|
392
489
|
#
|
393
490
|
# === Collections
|
394
491
|
#
|
395
|
-
# * Adding an object to a collection (
|
492
|
+
# * Adding an object to a collection (#has_many or #has_and_belongs_to_many) automatically
|
396
493
|
# saves that object, except if the parent object (the owner of the collection) is not yet
|
397
494
|
# stored in the database.
|
398
495
|
# * If saving any of the objects being added to a collection (via <tt>push</tt> or similar)
|
399
496
|
# fails, then <tt>push</tt> returns +false+.
|
400
497
|
# * If saving fails while replacing the collection (via <tt>association=</tt>), an
|
401
|
-
#
|
498
|
+
# ActiveRecord::RecordNotSaved exception is raised and the assignment is
|
402
499
|
# cancelled.
|
403
500
|
# * You can add an object to a collection without automatically saving it by using the
|
404
501
|
# <tt>collection.build</tt> method (documented below).
|
@@ -407,14 +504,14 @@ module ActiveRecord
|
|
407
504
|
#
|
408
505
|
# == Customizing the query
|
409
506
|
#
|
410
|
-
# \Associations are built from <tt>Relation</tt>
|
507
|
+
# \Associations are built from <tt>Relation</tt> objects, and you can use the Relation syntax
|
411
508
|
# to customize them. For example, to add a condition:
|
412
509
|
#
|
413
510
|
# class Blog < ActiveRecord::Base
|
414
|
-
# has_many :published_posts, -> { where
|
511
|
+
# has_many :published_posts, -> { where(published: true) }, class_name: 'Post'
|
415
512
|
# end
|
416
513
|
#
|
417
|
-
# Inside the <tt>-> { ... }</tt> block you can use all of the usual
|
514
|
+
# Inside the <tt>-> { ... }</tt> block you can use all of the usual Relation methods.
|
418
515
|
#
|
419
516
|
# === Accessing the owner object
|
420
517
|
#
|
@@ -423,7 +520,7 @@ module ActiveRecord
|
|
423
520
|
# events that occur on the user's birthday:
|
424
521
|
#
|
425
522
|
# class User < ActiveRecord::Base
|
426
|
-
# has_many :birthday_events, ->(user) { where
|
523
|
+
# has_many :birthday_events, ->(user) { where(starts_on: user.birthday) }, class_name: 'Event'
|
427
524
|
# end
|
428
525
|
#
|
429
526
|
# Note: Joining, eager loading and preloading of these associations is not fully possible.
|
@@ -502,8 +599,8 @@ module ActiveRecord
|
|
502
599
|
#
|
503
600
|
# * <tt>record.association(:items).owner</tt> - Returns the object the association is part of.
|
504
601
|
# * <tt>record.association(:items).reflection</tt> - Returns the reflection object that describes the association.
|
505
|
-
# * <tt>record.association(:items).target</tt> - Returns the associated object for
|
506
|
-
# the collection of associated objects for
|
602
|
+
# * <tt>record.association(:items).target</tt> - Returns the associated object for #belongs_to and #has_one, or
|
603
|
+
# the collection of associated objects for #has_many and #has_and_belongs_to_many.
|
507
604
|
#
|
508
605
|
# However, inside the actual extension code, you will not have access to the <tt>record</tt> as
|
509
606
|
# above. In this case, you can access <tt>proxy_association</tt>. For example,
|
@@ -515,7 +612,7 @@ module ActiveRecord
|
|
515
612
|
#
|
516
613
|
# Has Many associations can be configured with the <tt>:through</tt> option to use an
|
517
614
|
# explicit join model to retrieve the data. This operates similarly to a
|
518
|
-
#
|
615
|
+
# #has_and_belongs_to_many association. The advantage is that you're able to add validations,
|
519
616
|
# callbacks, and extra attributes on the join model. Consider the following schema:
|
520
617
|
#
|
521
618
|
# class Author < ActiveRecord::Base
|
@@ -532,7 +629,7 @@ module ActiveRecord
|
|
532
629
|
# @author.authorships.collect { |a| a.book } # selects all books that the author's authorships belong to
|
533
630
|
# @author.books # selects all books by using the Authorship join model
|
534
631
|
#
|
535
|
-
# You can also go through a
|
632
|
+
# You can also go through a #has_many association on the join model:
|
536
633
|
#
|
537
634
|
# class Firm < ActiveRecord::Base
|
538
635
|
# has_many :clients
|
@@ -552,7 +649,7 @@ module ActiveRecord
|
|
552
649
|
# @firm.clients.flat_map { |c| c.invoices } # select all invoices for all clients of the firm
|
553
650
|
# @firm.invoices # selects all invoices by going through the Client join model
|
554
651
|
#
|
555
|
-
# Similarly you can go through a
|
652
|
+
# Similarly you can go through a #has_one association on the join model:
|
556
653
|
#
|
557
654
|
# class Group < ActiveRecord::Base
|
558
655
|
# has_many :users
|
@@ -572,7 +669,7 @@ module ActiveRecord
|
|
572
669
|
# @group.users.collect { |u| u.avatar }.compact # select all avatars for all users in the group
|
573
670
|
# @group.avatars # selects all avatars by going through the User join model.
|
574
671
|
#
|
575
|
-
# An important caveat with going through
|
672
|
+
# An important caveat with going through #has_one or #has_many associations on the
|
576
673
|
# join model is that these associations are *read-only*. For example, the following
|
577
674
|
# would not work following the previous example:
|
578
675
|
#
|
@@ -581,26 +678,26 @@ module ActiveRecord
|
|
581
678
|
#
|
582
679
|
# == Setting Inverses
|
583
680
|
#
|
584
|
-
# If you are using a
|
585
|
-
# <tt>:inverse_of</tt> option on the
|
586
|
-
# works correctly (where <tt>tags</tt> is a
|
681
|
+
# If you are using a #belongs_to on the join model, it is a good idea to set the
|
682
|
+
# <tt>:inverse_of</tt> option on the #belongs_to, which will mean that the following example
|
683
|
+
# works correctly (where <tt>tags</tt> is a #has_many <tt>:through</tt> association):
|
587
684
|
#
|
588
685
|
# @post = Post.first
|
589
686
|
# @tag = @post.tags.build name: "ruby"
|
590
687
|
# @tag.save
|
591
688
|
#
|
592
|
-
# The last line ought to save the through record (a <tt>
|
689
|
+
# The last line ought to save the through record (a <tt>Tagging</tt>). This will only work if the
|
593
690
|
# <tt>:inverse_of</tt> is set:
|
594
691
|
#
|
595
|
-
# class
|
692
|
+
# class Tagging < ActiveRecord::Base
|
596
693
|
# belongs_to :post
|
597
694
|
# belongs_to :tag, inverse_of: :taggings
|
598
695
|
# end
|
599
696
|
#
|
600
697
|
# If you do not set the <tt>:inverse_of</tt> record, the association will
|
601
698
|
# do its best to match itself up with the correct inverse. Automatic
|
602
|
-
# inverse detection only works on
|
603
|
-
#
|
699
|
+
# inverse detection only works on #has_many, #has_one, and
|
700
|
+
# #belongs_to associations.
|
604
701
|
#
|
605
702
|
# Extra options on the associations, as defined in the
|
606
703
|
# <tt>AssociationReflection::INVALID_AUTOMATIC_INVERSE_OPTIONS</tt> constant, will
|
@@ -613,7 +710,7 @@ module ActiveRecord
|
|
613
710
|
# You can turn off the automatic detection of inverse associations by setting
|
614
711
|
# the <tt>:inverse_of</tt> option to <tt>false</tt> like so:
|
615
712
|
#
|
616
|
-
# class
|
713
|
+
# class Tagging < ActiveRecord::Base
|
617
714
|
# belongs_to :tag, inverse_of: false
|
618
715
|
# end
|
619
716
|
#
|
@@ -663,7 +760,7 @@ module ActiveRecord
|
|
663
760
|
# == Polymorphic \Associations
|
664
761
|
#
|
665
762
|
# Polymorphic associations on models are not restricted on what types of models they
|
666
|
-
# can be associated with. Rather, they specify an interface that a
|
763
|
+
# can be associated with. Rather, they specify an interface that a #has_many association
|
667
764
|
# must adhere to.
|
668
765
|
#
|
669
766
|
# class Asset < ActiveRecord::Base
|
@@ -747,7 +844,7 @@ module ActiveRecord
|
|
747
844
|
#
|
748
845
|
# Post.includes(:author).each do |post|
|
749
846
|
#
|
750
|
-
# This references the name of the
|
847
|
+
# This references the name of the #belongs_to association that also used the <tt>:author</tt>
|
751
848
|
# symbol. After loading the posts, find will collect the +author_id+ from each one and load
|
752
849
|
# all the referenced authors with one query. Doing so will cut down the number of queries
|
753
850
|
# from 201 to 102.
|
@@ -758,7 +855,7 @@ module ActiveRecord
|
|
758
855
|
#
|
759
856
|
# This will load all comments with a single query. This reduces the total number of queries
|
760
857
|
# to 3. In general, the number of queries will be 1 plus the number of associations
|
761
|
-
# named (except if some of the associations are polymorphic
|
858
|
+
# named (except if some of the associations are polymorphic #belongs_to - see below).
|
762
859
|
#
|
763
860
|
# To include a deep hierarchy of associations, use a hash:
|
764
861
|
#
|
@@ -798,7 +895,7 @@ module ActiveRecord
|
|
798
895
|
# In this case it is usually more natural to include an association which has conditions defined on it:
|
799
896
|
#
|
800
897
|
# class Post < ActiveRecord::Base
|
801
|
-
# has_many :approved_comments, -> { where
|
898
|
+
# has_many :approved_comments, -> { where(approved: true) }, class_name: 'Comment'
|
802
899
|
# end
|
803
900
|
#
|
804
901
|
# Post.includes(:approved_comments)
|
@@ -830,7 +927,7 @@ module ActiveRecord
|
|
830
927
|
# For example if all the addressables are either of class Person or Company then a total
|
831
928
|
# of 3 queries will be executed. The list of addressable types to load is determined on
|
832
929
|
# the back of the addresses loaded. This is not supported if Active Record has to fallback
|
833
|
-
# to the previous implementation of eager loading and will raise
|
930
|
+
# to the previous implementation of eager loading and will raise ActiveRecord::EagerLoadPolymorphicError.
|
834
931
|
# The reason is that the parent model's type is a column value so its corresponding table
|
835
932
|
# name cannot be put in the +FROM+/+JOIN+ clauses of that query.
|
836
933
|
#
|
@@ -872,7 +969,7 @@ module ActiveRecord
|
|
872
969
|
# INNER JOIN categories_posts posts_categories_join INNER JOIN posts posts_categories
|
873
970
|
# INNER JOIN categories_posts categories_posts_join INNER JOIN categories categories_posts_2
|
874
971
|
#
|
875
|
-
# If you wish to specify your own custom joins using
|
972
|
+
# If you wish to specify your own custom joins using ActiveRecord::QueryMethods#joins method, those table
|
876
973
|
# names will take precedence over the eager associations:
|
877
974
|
#
|
878
975
|
# Post.joins(:comments).joins("inner join comments ...")
|
@@ -937,20 +1034,16 @@ module ActiveRecord
|
|
937
1034
|
# The +traps+ association on +Dungeon+ and the +dungeon+ association on +Trap+ are
|
938
1035
|
# the inverse of each other and the inverse of the +dungeon+ association on +EvilWizard+
|
939
1036
|
# is the +evil_wizard+ association on +Dungeon+ (and vice-versa). By default,
|
940
|
-
# Active Record
|
941
|
-
#
|
1037
|
+
# Active Record can guess the inverse of the association based on the name
|
1038
|
+
# of the class. The result is the following:
|
942
1039
|
#
|
943
1040
|
# d = Dungeon.first
|
944
1041
|
# t = d.traps.first
|
945
|
-
# d.
|
946
|
-
# d.level = 10
|
947
|
-
# d.level == t.dungeon.level # => false
|
1042
|
+
# d.object_id == t.dungeon.object_id # => true
|
948
1043
|
#
|
949
1044
|
# The +Dungeon+ instances +d+ and <tt>t.dungeon</tt> in the above example refer to
|
950
|
-
# the same
|
951
|
-
#
|
952
|
-
# Active Record about inverse relationships and it will optimise object loading. For
|
953
|
-
# example, if we changed our model definitions to:
|
1045
|
+
# the same in-memory instance since the association matches the name of the class.
|
1046
|
+
# The result would be the same if we added +:inverse_of+ to our model definitions:
|
954
1047
|
#
|
955
1048
|
# class Dungeon < ActiveRecord::Base
|
956
1049
|
# has_many :traps, inverse_of: :dungeon
|
@@ -965,20 +1058,19 @@ module ActiveRecord
|
|
965
1058
|
# belongs_to :dungeon, inverse_of: :evil_wizard
|
966
1059
|
# end
|
967
1060
|
#
|
968
|
-
# Then, from our code snippet above, +d+ and <tt>t.dungeon</tt> are actually the same
|
969
|
-
# in-memory instance and our final <tt>d.level == t.dungeon.level</tt> will return +true+.
|
970
|
-
#
|
971
1061
|
# There are limitations to <tt>:inverse_of</tt> support:
|
972
1062
|
#
|
973
1063
|
# * does not work with <tt>:through</tt> associations.
|
974
1064
|
# * does not work with <tt>:polymorphic</tt> associations.
|
975
|
-
# * for
|
1065
|
+
# * for #belongs_to associations #has_many inverse associations are ignored.
|
1066
|
+
#
|
1067
|
+
# For more information, see the documentation for the +:inverse_of+ option.
|
976
1068
|
#
|
977
1069
|
# == Deleting from associations
|
978
1070
|
#
|
979
1071
|
# === Dependent associations
|
980
1072
|
#
|
981
|
-
#
|
1073
|
+
# #has_many, #has_one and #belongs_to associations support the <tt>:dependent</tt> option.
|
982
1074
|
# This allows you to specify that associated records should be deleted when the owner is
|
983
1075
|
# deleted.
|
984
1076
|
#
|
@@ -999,20 +1091,22 @@ module ActiveRecord
|
|
999
1091
|
# callbacks declared either before or after the <tt>:dependent</tt> option
|
1000
1092
|
# can affect what it does.
|
1001
1093
|
#
|
1094
|
+
# Note that <tt>:dependent</tt> option is ignored for #has_one <tt>:through</tt> associations.
|
1095
|
+
#
|
1002
1096
|
# === Delete or destroy?
|
1003
1097
|
#
|
1004
|
-
#
|
1098
|
+
# #has_many and #has_and_belongs_to_many associations have the methods <tt>destroy</tt>,
|
1005
1099
|
# <tt>delete</tt>, <tt>destroy_all</tt> and <tt>delete_all</tt>.
|
1006
1100
|
#
|
1007
|
-
# For
|
1101
|
+
# For #has_and_belongs_to_many, <tt>delete</tt> and <tt>destroy</tt> are the same: they
|
1008
1102
|
# cause the records in the join table to be removed.
|
1009
1103
|
#
|
1010
|
-
# For
|
1104
|
+
# For #has_many, <tt>destroy</tt> and <tt>destroy_all</tt> will always call the <tt>destroy</tt> method of the
|
1011
1105
|
# record(s) being removed so that callbacks are run. However <tt>delete</tt> and <tt>delete_all</tt> will either
|
1012
1106
|
# do the deletion according to the strategy specified by the <tt>:dependent</tt> option, or
|
1013
1107
|
# if no <tt>:dependent</tt> option is given, then it will follow the default strategy.
|
1014
|
-
# The default strategy is
|
1015
|
-
#
|
1108
|
+
# The default strategy is to do nothing (leave the foreign keys with the parent ids set), except for
|
1109
|
+
# #has_many <tt>:through</tt>, where the default strategy is <tt>delete_all</tt> (delete
|
1016
1110
|
# the join records, without running their callbacks).
|
1017
1111
|
#
|
1018
1112
|
# There is also a <tt>clear</tt> method which is the same as <tt>delete_all</tt>, except that
|
@@ -1020,13 +1114,13 @@ module ActiveRecord
|
|
1020
1114
|
#
|
1021
1115
|
# === What gets deleted?
|
1022
1116
|
#
|
1023
|
-
# There is a potential pitfall here:
|
1117
|
+
# There is a potential pitfall here: #has_and_belongs_to_many and #has_many <tt>:through</tt>
|
1024
1118
|
# associations have records in join tables, as well as the associated records. So when we
|
1025
1119
|
# call one of these deletion methods, what exactly should be deleted?
|
1026
1120
|
#
|
1027
1121
|
# The answer is that it is assumed that deletion on an association is about removing the
|
1028
1122
|
# <i>link</i> between the owner and the associated object(s), rather than necessarily the
|
1029
|
-
# associated objects themselves. So with
|
1123
|
+
# associated objects themselves. So with #has_and_belongs_to_many and #has_many
|
1030
1124
|
# <tt>:through</tt>, the join records will be deleted, but the associated records won't.
|
1031
1125
|
#
|
1032
1126
|
# This makes sense if you think about it: if you were to call <tt>post.tags.delete(Tag.find_by(name: 'food'))</tt>
|
@@ -1037,20 +1131,20 @@ module ActiveRecord
|
|
1037
1131
|
# a person has many projects, and each project has many tasks. If we deleted one of a person's
|
1038
1132
|
# tasks, we would probably not want the project to be deleted. In this scenario, the delete method
|
1039
1133
|
# won't actually work: it can only be used if the association on the join model is a
|
1040
|
-
#
|
1134
|
+
# #belongs_to. In other situations you are expected to perform operations directly on
|
1041
1135
|
# either the associated records or the <tt>:through</tt> association.
|
1042
1136
|
#
|
1043
|
-
# With a regular
|
1137
|
+
# With a regular #has_many there is no distinction between the "associated records"
|
1044
1138
|
# and the "link", so there is only one choice for what gets deleted.
|
1045
1139
|
#
|
1046
|
-
# With
|
1140
|
+
# With #has_and_belongs_to_many and #has_many <tt>:through</tt>, if you want to delete the
|
1047
1141
|
# associated records themselves, you can always do something along the lines of
|
1048
1142
|
# <tt>person.tasks.each(&:destroy)</tt>.
|
1049
1143
|
#
|
1050
|
-
# == Type safety with
|
1144
|
+
# == Type safety with ActiveRecord::AssociationTypeMismatch
|
1051
1145
|
#
|
1052
1146
|
# If you attempt to assign an object to an association that doesn't match the inferred
|
1053
|
-
# or specified <tt>:class_name</tt>, you'll get an
|
1147
|
+
# or specified <tt>:class_name</tt>, you'll get an ActiveRecord::AssociationTypeMismatch.
|
1054
1148
|
#
|
1055
1149
|
# == Options
|
1056
1150
|
#
|
@@ -1070,6 +1164,7 @@ module ActiveRecord
|
|
1070
1164
|
# Adds one or more objects to the collection by setting their foreign keys to the collection's primary key.
|
1071
1165
|
# Note that this operation instantly fires update SQL without waiting for the save or update call on the
|
1072
1166
|
# parent object, unless the parent object is a new record.
|
1167
|
+
# This will also run validations and callbacks of associated object(s).
|
1073
1168
|
# [collection.delete(object, ...)]
|
1074
1169
|
# Removes one or more objects from the collection by setting their foreign keys to +NULL+.
|
1075
1170
|
# Objects will be in addition destroyed if they're associated with <tt>dependent: :destroy</tt>,
|
@@ -1087,7 +1182,8 @@ module ActiveRecord
|
|
1087
1182
|
# [collection=objects]
|
1088
1183
|
# Replaces the collections content by deleting and adding objects as appropriate. If the <tt>:through</tt>
|
1089
1184
|
# option is true callbacks in the join models are triggered except destroy callbacks, since deletion is
|
1090
|
-
# direct.
|
1185
|
+
# direct by default. You can specify <tt>dependent: :destroy</tt> or
|
1186
|
+
# <tt>dependent: :nullify</tt> to override this.
|
1091
1187
|
# [collection_singular_ids]
|
1092
1188
|
# Returns an array of the associated objects' ids
|
1093
1189
|
# [collection_singular_ids=ids]
|
@@ -1104,10 +1200,10 @@ module ActiveRecord
|
|
1104
1200
|
# [collection.size]
|
1105
1201
|
# Returns the number of associated objects.
|
1106
1202
|
# [collection.find(...)]
|
1107
|
-
# Finds an associated object according to the same rules as
|
1203
|
+
# Finds an associated object according to the same rules as ActiveRecord::FinderMethods#find.
|
1108
1204
|
# [collection.exists?(...)]
|
1109
1205
|
# Checks whether an associated object with the given conditions exists.
|
1110
|
-
# Uses the same rules as
|
1206
|
+
# Uses the same rules as ActiveRecord::FinderMethods#exists?.
|
1111
1207
|
# [collection.build(attributes = {}, ...)]
|
1112
1208
|
# Returns one or more new objects of the collection type that have been instantiated
|
1113
1209
|
# with +attributes+ and linked to this object through a foreign key, but have not yet
|
@@ -1118,7 +1214,7 @@ module ActiveRecord
|
|
1118
1214
|
# been saved (if it passed the validation). *Note*: This only works if the base model
|
1119
1215
|
# already exists in the DB, not if it is a new (unsaved) record!
|
1120
1216
|
# [collection.create!(attributes = {})]
|
1121
|
-
# Does the same as <tt>collection.create</tt>, but raises
|
1217
|
+
# Does the same as <tt>collection.create</tt>, but raises ActiveRecord::RecordInvalid
|
1122
1218
|
# if the record is invalid.
|
1123
1219
|
#
|
1124
1220
|
# === Example
|
@@ -1170,11 +1266,11 @@ module ActiveRecord
|
|
1170
1266
|
# [:class_name]
|
1171
1267
|
# Specify the class name of the association. Use it only if that name can't be inferred
|
1172
1268
|
# from the association name. So <tt>has_many :products</tt> will by default be linked
|
1173
|
-
# to the Product class, but if the real class name is SpecialProduct
|
1269
|
+
# to the +Product+ class, but if the real class name is +SpecialProduct+, you'll have to
|
1174
1270
|
# specify it with this option.
|
1175
1271
|
# [:foreign_key]
|
1176
1272
|
# Specify the foreign key used for the association. By default this is guessed to be the name
|
1177
|
-
# of this class in lower-case and "_id" suffixed. So a Person class that makes a
|
1273
|
+
# of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_many
|
1178
1274
|
# association will use "person_id" as the default <tt>:foreign_key</tt>.
|
1179
1275
|
# [:foreign_type]
|
1180
1276
|
# Specify the column used to store the associated object's type, if this is a polymorphic
|
@@ -1198,20 +1294,20 @@ module ActiveRecord
|
|
1198
1294
|
# * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there are any associated objects.
|
1199
1295
|
#
|
1200
1296
|
# If using with the <tt>:through</tt> option, the association on the join model must be
|
1201
|
-
# a
|
1297
|
+
# a #belongs_to, and the records which get deleted are the join records, rather than
|
1202
1298
|
# the associated records.
|
1203
1299
|
# [:counter_cache]
|
1204
1300
|
# This option can be used to configure a custom named <tt>:counter_cache.</tt> You only need this option,
|
1205
|
-
# when you customized the name of your <tt>:counter_cache</tt> on the
|
1301
|
+
# when you customized the name of your <tt>:counter_cache</tt> on the #belongs_to association.
|
1206
1302
|
# [:as]
|
1207
|
-
# Specifies a polymorphic interface (See
|
1303
|
+
# Specifies a polymorphic interface (See #belongs_to).
|
1208
1304
|
# [:through]
|
1209
1305
|
# Specifies an association through which to perform the query. This can be any other type
|
1210
1306
|
# of association, including other <tt>:through</tt> associations. Options for <tt>:class_name</tt>,
|
1211
1307
|
# <tt>:primary_key</tt> and <tt>:foreign_key</tt> are ignored, as the association uses the
|
1212
1308
|
# source reflection.
|
1213
1309
|
#
|
1214
|
-
# If the association on the join model is a
|
1310
|
+
# If the association on the join model is a #belongs_to, the collection can be modified
|
1215
1311
|
# and the records on the <tt>:through</tt> model will be automatically created and removed
|
1216
1312
|
# as appropriate. Otherwise, the collection is read-only, so you should manipulate the
|
1217
1313
|
# <tt>:through</tt> association directly.
|
@@ -1222,15 +1318,16 @@ module ActiveRecord
|
|
1222
1318
|
# the appropriate join model records when they are saved. (See the 'Association Join Models'
|
1223
1319
|
# section above.)
|
1224
1320
|
# [:source]
|
1225
|
-
# Specifies the source association name used by <tt
|
1321
|
+
# Specifies the source association name used by #has_many <tt>:through</tt> queries.
|
1226
1322
|
# Only use it if the name cannot be inferred from the association.
|
1227
1323
|
# <tt>has_many :subscribers, through: :subscriptions</tt> will look for either <tt>:subscribers</tt> or
|
1228
1324
|
# <tt>:subscriber</tt> on Subscription, unless a <tt>:source</tt> is given.
|
1229
1325
|
# [:source_type]
|
1230
|
-
# Specifies type of the source association used by <tt
|
1231
|
-
# association is a polymorphic
|
1326
|
+
# Specifies type of the source association used by #has_many <tt>:through</tt> queries where the source
|
1327
|
+
# association is a polymorphic #belongs_to.
|
1232
1328
|
# [:validate]
|
1233
|
-
#
|
1329
|
+
# When set to +true+, validates new objects added to association when saving the parent object. +true+ by default.
|
1330
|
+
# If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
|
1234
1331
|
# [:autosave]
|
1235
1332
|
# If true, always save the associated objects or destroy them if marked for destruction,
|
1236
1333
|
# when saving the parent object. If false, never save or destroy the associated objects.
|
@@ -1238,18 +1335,23 @@ module ActiveRecord
|
|
1238
1335
|
# +before_save+ callback. Because callbacks are run in the order they are defined, associated objects
|
1239
1336
|
# may need to be explicitly saved in any user-defined +before_save+ callbacks.
|
1240
1337
|
#
|
1241
|
-
# Note that
|
1338
|
+
# Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
|
1339
|
+
# <tt>:autosave</tt> to <tt>true</tt>.
|
1242
1340
|
# [:inverse_of]
|
1243
|
-
# Specifies the name of the
|
1244
|
-
# that is the inverse of this
|
1341
|
+
# Specifies the name of the #belongs_to association on the associated object
|
1342
|
+
# that is the inverse of this #has_many association. Does not work in combination
|
1245
1343
|
# with <tt>:through</tt> or <tt>:as</tt> options.
|
1246
1344
|
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
|
1345
|
+
# [:extend]
|
1346
|
+
# Specifies a module or array of modules that will be extended into the association object returned.
|
1347
|
+
# Useful for defining methods on associations, especially when they should be shared between multiple
|
1348
|
+
# association objects.
|
1247
1349
|
#
|
1248
1350
|
# Option examples:
|
1249
|
-
# has_many :comments, -> { order
|
1250
|
-
# has_many :comments, -> { includes
|
1351
|
+
# has_many :comments, -> { order("posted_on") }
|
1352
|
+
# has_many :comments, -> { includes(:author) }
|
1251
1353
|
# has_many :people, -> { where(deleted: false).order("name") }, class_name: "Person"
|
1252
|
-
# has_many :tracks, -> { order
|
1354
|
+
# has_many :tracks, -> { order("position") }, dependent: :destroy
|
1253
1355
|
# has_many :comments, dependent: :nullify
|
1254
1356
|
# has_many :tags, as: :taggable
|
1255
1357
|
# has_many :reports, -> { readonly }
|
@@ -1261,8 +1363,8 @@ module ActiveRecord
|
|
1261
1363
|
|
1262
1364
|
# Specifies a one-to-one association with another class. This method should only be used
|
1263
1365
|
# if the other class contains the foreign key. If the current class contains the foreign key,
|
1264
|
-
# then you should use
|
1265
|
-
# on when to use
|
1366
|
+
# then you should use #belongs_to instead. See also ActiveRecord::Associations::ClassMethods's overview
|
1367
|
+
# on when to use #has_one and when to use #belongs_to.
|
1266
1368
|
#
|
1267
1369
|
# The following methods for retrieval and query of a single associated object will be added:
|
1268
1370
|
#
|
@@ -1284,7 +1386,7 @@ module ActiveRecord
|
|
1284
1386
|
# with +attributes+, linked to this object through a foreign key, and that
|
1285
1387
|
# has already been saved (if it passed the validation).
|
1286
1388
|
# [create_association!(attributes = {})]
|
1287
|
-
# Does the same as <tt>create_association</tt>, but raises
|
1389
|
+
# Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
|
1288
1390
|
# if the record is invalid.
|
1289
1391
|
#
|
1290
1392
|
# === Example
|
@@ -1325,9 +1427,11 @@ module ActiveRecord
|
|
1325
1427
|
# * <tt>:nullify</tt> causes the foreign key to be set to +NULL+. Callbacks are not executed.
|
1326
1428
|
# * <tt>:restrict_with_exception</tt> causes an exception to be raised if there is an associated record
|
1327
1429
|
# * <tt>:restrict_with_error</tt> causes an error to be added to the owner if there is an associated object
|
1430
|
+
#
|
1431
|
+
# Note that <tt>:dependent</tt> option is ignored when using <tt>:through</tt> option.
|
1328
1432
|
# [:foreign_key]
|
1329
1433
|
# Specify the foreign key used for the association. By default this is guessed to be the name
|
1330
|
-
# of this class in lower-case and "_id" suffixed. So a Person class that makes a
|
1434
|
+
# of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_one association
|
1331
1435
|
# will use "person_id" as the default <tt>:foreign_key</tt>.
|
1332
1436
|
# [:foreign_type]
|
1333
1437
|
# Specify the column used to store the associated object's type, if this is a polymorphic
|
@@ -1338,31 +1442,33 @@ module ActiveRecord
|
|
1338
1442
|
# [:primary_key]
|
1339
1443
|
# Specify the method that returns the primary key used for the association. By default this is +id+.
|
1340
1444
|
# [:as]
|
1341
|
-
# Specifies a polymorphic interface (See
|
1445
|
+
# Specifies a polymorphic interface (See #belongs_to).
|
1342
1446
|
# [:through]
|
1343
1447
|
# Specifies a Join Model through which to perform the query. Options for <tt>:class_name</tt>,
|
1344
1448
|
# <tt>:primary_key</tt>, and <tt>:foreign_key</tt> are ignored, as the association uses the
|
1345
|
-
# source reflection. You can only use a <tt>:through</tt> query through a
|
1346
|
-
# or
|
1449
|
+
# source reflection. You can only use a <tt>:through</tt> query through a #has_one
|
1450
|
+
# or #belongs_to association on the join model.
|
1347
1451
|
# [:source]
|
1348
|
-
# Specifies the source association name used by <tt
|
1452
|
+
# Specifies the source association name used by #has_one <tt>:through</tt> queries.
|
1349
1453
|
# Only use it if the name cannot be inferred from the association.
|
1350
1454
|
# <tt>has_one :favorite, through: :favorites</tt> will look for a
|
1351
1455
|
# <tt>:favorite</tt> on Favorite, unless a <tt>:source</tt> is given.
|
1352
1456
|
# [:source_type]
|
1353
|
-
# Specifies type of the source association used by <tt
|
1354
|
-
# association is a polymorphic
|
1457
|
+
# Specifies type of the source association used by #has_one <tt>:through</tt> queries where the source
|
1458
|
+
# association is a polymorphic #belongs_to.
|
1355
1459
|
# [:validate]
|
1356
|
-
#
|
1460
|
+
# When set to +true+, validates new objects added to association when saving the parent object. +false+ by default.
|
1461
|
+
# If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
|
1357
1462
|
# [:autosave]
|
1358
1463
|
# If true, always save the associated object or destroy it if marked for destruction,
|
1359
1464
|
# when saving the parent object. If false, never save or destroy the associated object.
|
1360
1465
|
# By default, only save the associated object if it's a new record.
|
1361
1466
|
#
|
1362
|
-
# Note that
|
1467
|
+
# Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
|
1468
|
+
# <tt>:autosave</tt> to <tt>true</tt>.
|
1363
1469
|
# [:inverse_of]
|
1364
|
-
# Specifies the name of the
|
1365
|
-
# that is the inverse of this
|
1470
|
+
# Specifies the name of the #belongs_to association on the associated object
|
1471
|
+
# that is the inverse of this #has_one association. Does not work in combination
|
1366
1472
|
# with <tt>:through</tt> or <tt>:as</tt> options.
|
1367
1473
|
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
|
1368
1474
|
# [:required]
|
@@ -1374,12 +1480,12 @@ module ActiveRecord
|
|
1374
1480
|
# has_one :credit_card, dependent: :destroy # destroys the associated credit card
|
1375
1481
|
# has_one :credit_card, dependent: :nullify # updates the associated records foreign
|
1376
1482
|
# # key value to NULL rather than destroying it
|
1377
|
-
# has_one :last_comment, -> { order
|
1378
|
-
# has_one :project_manager, -> { where
|
1483
|
+
# has_one :last_comment, -> { order('posted_on') }, class_name: "Comment"
|
1484
|
+
# has_one :project_manager, -> { where(role: 'project_manager') }, class_name: "Person"
|
1379
1485
|
# has_one :attachment, as: :attachable
|
1380
|
-
# has_one :boss, readonly
|
1486
|
+
# has_one :boss, -> { readonly }
|
1381
1487
|
# has_one :club, through: :membership
|
1382
|
-
# has_one :primary_address, -> { where
|
1488
|
+
# has_one :primary_address, -> { where(primary: true) }, through: :addressables, source: :addressable
|
1383
1489
|
# has_one :credit_card, required: true
|
1384
1490
|
def has_one(name, scope = nil, options = {})
|
1385
1491
|
reflection = Builder::HasOne.build(self, name, scope, options)
|
@@ -1388,8 +1494,8 @@ module ActiveRecord
|
|
1388
1494
|
|
1389
1495
|
# Specifies a one-to-one association with another class. This method should only be used
|
1390
1496
|
# if this class contains the foreign key. If the other class contains the foreign key,
|
1391
|
-
# then you should use
|
1392
|
-
# on when to use
|
1497
|
+
# then you should use #has_one instead. See also ActiveRecord::Associations::ClassMethods's overview
|
1498
|
+
# on when to use #has_one and when to use #belongs_to.
|
1393
1499
|
#
|
1394
1500
|
# Methods will be added for retrieval and query for a single associated object, for which
|
1395
1501
|
# this object holds an id:
|
@@ -1409,7 +1515,7 @@ module ActiveRecord
|
|
1409
1515
|
# with +attributes+, linked to this object through a foreign key, and that
|
1410
1516
|
# has already been saved (if it passed the validation).
|
1411
1517
|
# [create_association!(attributes = {})]
|
1412
|
-
# Does the same as <tt>create_association</tt>, but raises
|
1518
|
+
# Does the same as <tt>create_association</tt>, but raises ActiveRecord::RecordInvalid
|
1413
1519
|
# if the record is invalid.
|
1414
1520
|
#
|
1415
1521
|
# === Example
|
@@ -1429,7 +1535,7 @@ module ActiveRecord
|
|
1429
1535
|
# when you access the associated object.
|
1430
1536
|
#
|
1431
1537
|
# Scope examples:
|
1432
|
-
# belongs_to :
|
1538
|
+
# belongs_to :firm, -> { where(id: 2) }
|
1433
1539
|
# belongs_to :user, -> { joins(:friends) }
|
1434
1540
|
# belongs_to :level, ->(level) { where("game_level > ?", level.current) }
|
1435
1541
|
#
|
@@ -1456,12 +1562,12 @@ module ActiveRecord
|
|
1456
1562
|
# [:dependent]
|
1457
1563
|
# If set to <tt>:destroy</tt>, the associated object is destroyed when this object is. If set to
|
1458
1564
|
# <tt>:delete</tt>, the associated object is deleted *without* calling its destroy method.
|
1459
|
-
# This option should not be specified when
|
1460
|
-
# a
|
1565
|
+
# This option should not be specified when #belongs_to is used in conjunction with
|
1566
|
+
# a #has_many relationship on another class because of the potential to leave
|
1461
1567
|
# orphaned records behind.
|
1462
1568
|
# [:counter_cache]
|
1463
|
-
# Caches the number of belonging objects on the associate class through the use of
|
1464
|
-
# and
|
1569
|
+
# Caches the number of belonging objects on the associate class through the use of CounterCache::ClassMethods#increment_counter
|
1570
|
+
# and CounterCache::ClassMethods#decrement_counter. The counter cache is incremented when an object of this
|
1465
1571
|
# class is created and decremented when it's destroyed. This requires that a column
|
1466
1572
|
# named <tt>#{table_name}_count</tt> (such as +comments_count+ for a belonging Comment class)
|
1467
1573
|
# is used on the associate class (such as a Post class) - that is the migration for
|
@@ -1476,27 +1582,35 @@ module ActiveRecord
|
|
1476
1582
|
# Note: If you've enabled the counter cache, then you may want to add the counter cache attribute
|
1477
1583
|
# to the +attr_readonly+ list in the associated classes (e.g. <tt>class Post; attr_readonly :comments_count; end</tt>).
|
1478
1584
|
# [:validate]
|
1479
|
-
#
|
1585
|
+
# When set to +true+, validates new objects added to association when saving the parent object. +false+ by default.
|
1586
|
+
# If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
|
1480
1587
|
# [:autosave]
|
1481
1588
|
# If true, always save the associated object or destroy it if marked for destruction, when
|
1482
1589
|
# saving the parent object.
|
1483
1590
|
# If false, never save or destroy the associated object.
|
1484
1591
|
# By default, only save the associated object if it's a new record.
|
1485
1592
|
#
|
1486
|
-
# Note that
|
1593
|
+
# Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for
|
1594
|
+
# sets <tt>:autosave</tt> to <tt>true</tt>.
|
1487
1595
|
# [:touch]
|
1488
1596
|
# If true, the associated object will be touched (the updated_at/on attributes set to current time)
|
1489
1597
|
# when this record is either saved or destroyed. If you specify a symbol, that attribute
|
1490
1598
|
# will be updated with the current time in addition to the updated_at/on attribute.
|
1599
|
+
# Please note that with touching no validation is performed and only the +after_touch+,
|
1600
|
+
# +after_commit+ and +after_rollback+ callbacks are executed.
|
1491
1601
|
# [:inverse_of]
|
1492
|
-
# Specifies the name of the
|
1493
|
-
# object that is the inverse of this
|
1602
|
+
# Specifies the name of the #has_one or #has_many association on the associated
|
1603
|
+
# object that is the inverse of this #belongs_to association. Does not work in
|
1494
1604
|
# combination with the <tt>:polymorphic</tt> options.
|
1495
1605
|
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
|
1606
|
+
# [:optional]
|
1607
|
+
# When set to +true+, the association will not have its presence validated.
|
1496
1608
|
# [:required]
|
1497
1609
|
# When set to +true+, the association will also have its presence validated.
|
1498
1610
|
# This will validate the association itself, not the id. You can use
|
1499
1611
|
# +:inverse_of+ to avoid an extra query during validation.
|
1612
|
+
# NOTE: <tt>required</tt> is set to <tt>true</tt> by default and is deprecated. If
|
1613
|
+
# you don't want to have association presence validated, use <tt>optional: true</tt>.
|
1500
1614
|
#
|
1501
1615
|
# Option examples:
|
1502
1616
|
# belongs_to :firm, foreign_key: "client_of"
|
@@ -1505,11 +1619,11 @@ module ActiveRecord
|
|
1505
1619
|
# belongs_to :valid_coupon, ->(o) { where "discounts > ?", o.payments_count },
|
1506
1620
|
# class_name: "Coupon", foreign_key: "coupon_id"
|
1507
1621
|
# belongs_to :attachable, polymorphic: true
|
1508
|
-
# belongs_to :project, readonly
|
1622
|
+
# belongs_to :project, -> { readonly }
|
1509
1623
|
# belongs_to :post, counter_cache: true
|
1510
|
-
# belongs_to :
|
1624
|
+
# belongs_to :comment, touch: true
|
1511
1625
|
# belongs_to :company, touch: :employees_last_updated_at
|
1512
|
-
# belongs_to :
|
1626
|
+
# belongs_to :user, optional: true
|
1513
1627
|
def belongs_to(name, scope = nil, options = {})
|
1514
1628
|
reflection = Builder::BelongsTo.build(self, name, scope, options)
|
1515
1629
|
Reflection.add_reflection self, name, reflection
|
@@ -1532,12 +1646,9 @@ module ActiveRecord
|
|
1532
1646
|
# The join table should not have a primary key or a model associated with it. You must manually generate the
|
1533
1647
|
# join table with a migration such as this:
|
1534
1648
|
#
|
1535
|
-
# class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration
|
1649
|
+
# class CreateDevelopersProjectsJoinTable < ActiveRecord::Migration[5.0]
|
1536
1650
|
# def change
|
1537
|
-
#
|
1538
|
-
# t.integer :developer_id
|
1539
|
-
# t.integer :project_id
|
1540
|
-
# end
|
1651
|
+
# create_join_table :developers, :projects
|
1541
1652
|
# end
|
1542
1653
|
# end
|
1543
1654
|
#
|
@@ -1579,10 +1690,10 @@ module ActiveRecord
|
|
1579
1690
|
# [collection.find(id)]
|
1580
1691
|
# Finds an associated object responding to the +id+ and that
|
1581
1692
|
# meets the condition that it has to be associated with this object.
|
1582
|
-
# Uses the same rules as
|
1693
|
+
# Uses the same rules as ActiveRecord::FinderMethods#find.
|
1583
1694
|
# [collection.exists?(...)]
|
1584
1695
|
# Checks whether an associated object with the given conditions exists.
|
1585
|
-
# Uses the same rules as
|
1696
|
+
# Uses the same rules as ActiveRecord::FinderMethods#exists?.
|
1586
1697
|
# [collection.build(attributes = {})]
|
1587
1698
|
# Returns a new object of the collection type that has been instantiated
|
1588
1699
|
# with +attributes+ and linked to this object through the join table, but has not yet been saved.
|
@@ -1617,7 +1728,7 @@ module ActiveRecord
|
|
1617
1728
|
# query when you access the associated collection.
|
1618
1729
|
#
|
1619
1730
|
# Scope examples:
|
1620
|
-
# has_and_belongs_to_many :projects, -> { includes
|
1731
|
+
# has_and_belongs_to_many :projects, -> { includes(:milestones, :manager) }
|
1621
1732
|
# has_and_belongs_to_many :categories, ->(category) {
|
1622
1733
|
# where("default_category = ?", category.name)
|
1623
1734
|
# }
|
@@ -1646,32 +1757,32 @@ module ActiveRecord
|
|
1646
1757
|
# [:join_table]
|
1647
1758
|
# Specify the name of the join table if the default based on lexical order isn't what you want.
|
1648
1759
|
# <b>WARNING:</b> If you're overwriting the table name of either class, the +table_name+ method
|
1649
|
-
# MUST be declared underneath any
|
1760
|
+
# MUST be declared underneath any #has_and_belongs_to_many declaration in order to work.
|
1650
1761
|
# [:foreign_key]
|
1651
1762
|
# Specify the foreign key used for the association. By default this is guessed to be the name
|
1652
1763
|
# of this class in lower-case and "_id" suffixed. So a Person class that makes
|
1653
|
-
# a
|
1764
|
+
# a #has_and_belongs_to_many association to Project will use "person_id" as the
|
1654
1765
|
# default <tt>:foreign_key</tt>.
|
1655
1766
|
# [:association_foreign_key]
|
1656
1767
|
# Specify the foreign key used for the association on the receiving side of the association.
|
1657
1768
|
# By default this is guessed to be the name of the associated class in lower-case and "_id" suffixed.
|
1658
|
-
# So if a Person class makes a
|
1769
|
+
# So if a Person class makes a #has_and_belongs_to_many association to Project,
|
1659
1770
|
# the association will use "project_id" as the default <tt>:association_foreign_key</tt>.
|
1660
|
-
# [:readonly]
|
1661
|
-
# If true, all the associated objects are readonly through the association.
|
1662
1771
|
# [:validate]
|
1663
|
-
#
|
1772
|
+
# When set to +true+, validates new objects added to association when saving the parent object. +true+ by default.
|
1773
|
+
# If you want to ensure associated objects are revalidated on every update, use +validates_associated+.
|
1664
1774
|
# [:autosave]
|
1665
1775
|
# If true, always save the associated objects or destroy them if marked for destruction, when
|
1666
1776
|
# saving the parent object.
|
1667
1777
|
# If false, never save or destroy the associated objects.
|
1668
1778
|
# By default, only save associated objects that are new records.
|
1669
1779
|
#
|
1670
|
-
# Note that
|
1780
|
+
# Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets
|
1781
|
+
# <tt>:autosave</tt> to <tt>true</tt>.
|
1671
1782
|
#
|
1672
1783
|
# Option examples:
|
1673
1784
|
# has_and_belongs_to_many :projects
|
1674
|
-
# has_and_belongs_to_many :projects, -> { includes
|
1785
|
+
# has_and_belongs_to_many :projects, -> { includes(:milestones, :manager) }
|
1675
1786
|
# has_and_belongs_to_many :nations, class_name: "Country"
|
1676
1787
|
# has_and_belongs_to_many :categories, join_table: "prods_cats"
|
1677
1788
|
# has_and_belongs_to_many :categories, -> { readonly }
|
@@ -1687,16 +1798,14 @@ module ActiveRecord
|
|
1687
1798
|
|
1688
1799
|
join_model = builder.through_model
|
1689
1800
|
|
1690
|
-
# FIXME: we should move this to the internal constants. Also people
|
1691
|
-
# should never directly access this constant so I'm not happy about
|
1692
|
-
# setting it.
|
1693
1801
|
const_set join_model.name, join_model
|
1802
|
+
private_constant join_model.name
|
1694
1803
|
|
1695
1804
|
middle_reflection = builder.middle_reflection join_model
|
1696
1805
|
|
1697
1806
|
Builder::HasMany.define_callbacks self, middle_reflection
|
1698
1807
|
Reflection.add_reflection self, middle_reflection.name, middle_reflection
|
1699
|
-
middle_reflection.parent_reflection =
|
1808
|
+
middle_reflection.parent_reflection = habtm_reflection
|
1700
1809
|
|
1701
1810
|
include Module.new {
|
1702
1811
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
@@ -1712,12 +1821,12 @@ module ActiveRecord
|
|
1712
1821
|
hm_options[:through] = middle_reflection.name
|
1713
1822
|
hm_options[:source] = join_model.right_reflection.name
|
1714
1823
|
|
1715
|
-
[:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate, :join_table, :class_name].each do |k|
|
1824
|
+
[:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate, :join_table, :class_name, :extend].each do |k|
|
1716
1825
|
hm_options[k] = options[k] if options.key? k
|
1717
1826
|
end
|
1718
1827
|
|
1719
1828
|
has_many name, scope, hm_options, &extension
|
1720
|
-
self._reflections[name.to_s].parent_reflection =
|
1829
|
+
self._reflections[name.to_s].parent_reflection = habtm_reflection
|
1721
1830
|
end
|
1722
1831
|
end
|
1723
1832
|
end
|