activerecord 5.1.7 → 5.2.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 +372 -765
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -5
- data/examples/performance.rb +2 -0
- data/examples/simple.rb +2 -0
- data/lib/active_record/aggregations.rb +6 -5
- data/lib/active_record/association_relation.rb +4 -2
- data/lib/active_record/associations/alias_tracker.rb +19 -27
- data/lib/active_record/associations/association.rb +16 -27
- data/lib/active_record/associations/association_scope.rb +38 -50
- data/lib/active_record/associations/belongs_to_association.rb +20 -10
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +4 -7
- data/lib/active_record/associations/builder/association.rb +4 -7
- data/lib/active_record/associations/builder/belongs_to.rb +4 -5
- data/lib/active_record/associations/builder/collection_association.rb +1 -1
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +2 -0
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +43 -35
- data/lib/active_record/associations/collection_proxy.rb +12 -15
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +3 -1
- data/lib/active_record/associations/has_many_through_association.rb +7 -18
- data/lib/active_record/associations/has_one_association.rb +4 -1
- data/lib/active_record/associations/has_one_through_association.rb +8 -7
- data/lib/active_record/associations/join_dependency/join_association.rb +17 -56
- data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -9
- data/lib/active_record/associations/join_dependency.rb +23 -43
- data/lib/active_record/associations/preloader/association.rb +45 -61
- data/lib/active_record/associations/preloader/through_association.rb +71 -79
- data/lib/active_record/associations/preloader.rb +17 -37
- data/lib/active_record/associations/singular_association.rb +14 -10
- data/lib/active_record/associations/through_association.rb +25 -10
- data/lib/active_record/associations.rb +31 -54
- data/lib/active_record/attribute_assignment.rb +2 -5
- data/lib/active_record/attribute_decorators.rb +3 -2
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
- data/lib/active_record/attribute_methods/dirty.rb +25 -214
- data/lib/active_record/attribute_methods/primary_key.rb +7 -6
- data/lib/active_record/attribute_methods/query.rb +2 -0
- data/lib/active_record/attribute_methods/read.rb +8 -2
- data/lib/active_record/attribute_methods/serialization.rb +23 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
- data/lib/active_record/attribute_methods/write.rb +21 -9
- data/lib/active_record/attribute_methods.rb +65 -24
- data/lib/active_record/attributes.rb +6 -5
- data/lib/active_record/autosave_association.rb +8 -11
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +8 -10
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +2 -0
- data/lib/active_record/collection_cache_key.rb +11 -7
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +111 -38
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +157 -29
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +7 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +13 -32
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +14 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +57 -2
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +158 -78
- data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
- data/lib/active_record/connection_adapters/abstract_adapter.rb +81 -96
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +111 -183
- data/lib/active_record/connection_adapters/column.rb +3 -1
- data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +11 -2
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -10
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -30
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -1
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
- data/lib/active_record/connection_adapters/postgresql/column.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +4 -6
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +18 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +246 -110
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +58 -82
- data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +18 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +71 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +80 -90
- data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
- data/lib/active_record/connection_handling.rb +4 -2
- data/lib/active_record/core.rb +39 -60
- data/lib/active_record/counter_cache.rb +15 -12
- data/lib/active_record/define_callbacks.rb +5 -3
- data/lib/active_record/dynamic_matchers.rb +9 -9
- data/lib/active_record/enum.rb +17 -13
- data/lib/active_record/errors.rb +54 -21
- data/lib/active_record/explain.rb +3 -1
- data/lib/active_record/explain_registry.rb +2 -0
- data/lib/active_record/explain_subscriber.rb +2 -0
- data/lib/active_record/fixture_set/file.rb +2 -0
- data/lib/active_record/fixtures.rb +67 -60
- data/lib/active_record/gem_version.rb +4 -2
- data/lib/active_record/inheritance.rb +49 -19
- data/lib/active_record/integration.rb +58 -19
- data/lib/active_record/internal_metadata.rb +2 -0
- data/lib/active_record/legacy_yaml_adapter.rb +3 -1
- data/lib/active_record/locking/optimistic.rb +14 -17
- data/lib/active_record/locking/pessimistic.rb +9 -6
- data/lib/active_record/log_subscriber.rb +43 -0
- data/lib/active_record/migration/command_recorder.rb +11 -9
- data/lib/active_record/migration/compatibility.rb +40 -2
- data/lib/active_record/migration/join_table.rb +2 -0
- data/lib/active_record/migration.rb +189 -139
- data/lib/active_record/model_schema.rb +16 -21
- data/lib/active_record/nested_attributes.rb +18 -6
- data/lib/active_record/no_touching.rb +3 -1
- data/lib/active_record/null_relation.rb +2 -0
- data/lib/active_record/persistence.rb +166 -16
- data/lib/active_record/query_cache.rb +11 -6
- data/lib/active_record/querying.rb +3 -1
- data/lib/active_record/railtie.rb +61 -3
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +2 -0
- data/lib/active_record/railties/databases.rake +46 -36
- data/lib/active_record/readonly_attributes.rb +3 -2
- data/lib/active_record/reflection.rb +110 -192
- data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
- data/lib/active_record/relation/batches.rb +20 -5
- data/lib/active_record/relation/calculations.rb +30 -8
- data/lib/active_record/relation/delegation.rb +15 -27
- data/lib/active_record/relation/finder_methods.rb +75 -78
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +51 -20
- data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +26 -9
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/predicate_builder.rb +53 -78
- data/lib/active_record/relation/query_attribute.rb +26 -2
- data/lib/active_record/relation/query_methods.rb +89 -88
- data/lib/active_record/relation/record_fetch_warning.rb +2 -0
- data/lib/active_record/relation/spawn_methods.rb +3 -1
- data/lib/active_record/relation/where_clause.rb +65 -68
- data/lib/active_record/relation/where_clause_factory.rb +5 -48
- data/lib/active_record/relation.rb +95 -208
- data/lib/active_record/result.rb +2 -0
- data/lib/active_record/runtime_registry.rb +2 -0
- data/lib/active_record/sanitization.rb +129 -121
- data/lib/active_record/schema.rb +4 -2
- data/lib/active_record/schema_dumper.rb +36 -26
- data/lib/active_record/schema_migration.rb +2 -0
- data/lib/active_record/scoping/default.rb +6 -7
- data/lib/active_record/scoping/named.rb +21 -7
- data/lib/active_record/scoping.rb +9 -8
- data/lib/active_record/secure_token.rb +2 -0
- data/lib/active_record/serialization.rb +2 -0
- data/lib/active_record/statement_cache.rb +22 -12
- data/lib/active_record/store.rb +3 -1
- data/lib/active_record/suppressor.rb +2 -0
- data/lib/active_record/table_metadata.rb +12 -3
- data/lib/active_record/tasks/database_tasks.rb +26 -15
- data/lib/active_record/tasks/mysql_database_tasks.rb +9 -48
- data/lib/active_record/tasks/postgresql_database_tasks.rb +10 -2
- data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
- data/lib/active_record/timestamp.rb +5 -12
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +9 -7
- data/lib/active_record/translation.rb +2 -0
- data/lib/active_record/type/adapter_specific_registry.rb +2 -0
- data/lib/active_record/type/date.rb +2 -0
- data/lib/active_record/type/date_time.rb +2 -0
- data/lib/active_record/type/decimal_without_scale.rb +2 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
- data/lib/active_record/type/internal/timezone.rb +2 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +2 -4
- data/lib/active_record/type/text.rb +2 -0
- data/lib/active_record/type/time.rb +2 -0
- data/lib/active_record/type/type_map.rb +2 -0
- data/lib/active_record/type/unsigned_integer.rb +2 -0
- data/lib/active_record/type.rb +4 -1
- data/lib/active_record/type_caster/connection.rb +2 -0
- data/lib/active_record/type_caster/map.rb +3 -1
- data/lib/active_record/type_caster.rb +2 -0
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +2 -0
- data/lib/active_record/validations/length.rb +2 -0
- data/lib/active_record/validations/presence.rb +2 -0
- data/lib/active_record/validations/uniqueness.rb +35 -5
- data/lib/active_record/validations.rb +2 -0
- data/lib/active_record/version.rb +2 -0
- data/lib/active_record.rb +11 -4
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration.rb +2 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- data/lib/rails/generators/active_record.rb +3 -1
- metadata +24 -36
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
- data/lib/active_record/associations/preloader/collection_association.rb +0 -17
- data/lib/active_record/associations/preloader/has_many.rb +0 -15
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -15
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -18
- data/lib/active_record/attribute/user_provided_default.rb +0 -30
- data/lib/active_record/attribute.rb +0 -240
- data/lib/active_record/attribute_mutation_tracker.rb +0 -122
- data/lib/active_record/attribute_set/builder.rb +0 -126
- data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
- data/lib/active_record/attribute_set.rb +0 -113
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
- data/lib/active_record/type/internal/abstract_json.rb +0 -37
@@ -1,10 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
|
-
# = Active Record Through Association
|
3
4
|
module Associations
|
5
|
+
# = Active Record Through Association
|
4
6
|
module ThroughAssociation #:nodoc:
|
5
|
-
delegate :source_reflection,
|
7
|
+
delegate :source_reflection, to: :reflection
|
6
8
|
|
7
9
|
private
|
10
|
+
def through_reflection
|
11
|
+
@through_reflection ||= begin
|
12
|
+
refl = reflection.through_reflection
|
13
|
+
|
14
|
+
while refl.through_reflection?
|
15
|
+
refl = refl.through_reflection
|
16
|
+
end
|
17
|
+
|
18
|
+
refl
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def through_association
|
23
|
+
@through_association ||= owner.association(through_reflection.name)
|
24
|
+
end
|
8
25
|
|
9
26
|
# We merge in these scopes for two reasons:
|
10
27
|
#
|
@@ -36,24 +53,22 @@ module ActiveRecord
|
|
36
53
|
def construct_join_attributes(*records)
|
37
54
|
ensure_mutable
|
38
55
|
|
39
|
-
|
56
|
+
association_primary_key = source_reflection.association_primary_key(reflection.klass)
|
57
|
+
|
58
|
+
if association_primary_key == reflection.klass.primary_key && !options[:source_type]
|
40
59
|
join_attributes = { source_reflection.name => records }
|
41
60
|
else
|
42
61
|
join_attributes = {
|
43
|
-
source_reflection.foreign_key =>
|
44
|
-
records.map { |record|
|
45
|
-
record.send(source_reflection.association_primary_key(reflection.klass))
|
46
|
-
}
|
62
|
+
source_reflection.foreign_key => records.map(&association_primary_key.to_sym)
|
47
63
|
}
|
48
64
|
end
|
49
65
|
|
50
66
|
if options[:source_type]
|
51
|
-
join_attributes[source_reflection.foreign_type] =
|
52
|
-
records.map { |record| record.class.base_class.name }
|
67
|
+
join_attributes[source_reflection.foreign_type] = [ options[:source_type] ]
|
53
68
|
end
|
54
69
|
|
55
70
|
if records.count == 1
|
56
|
-
|
71
|
+
join_attributes.transform_values!(&:first)
|
57
72
|
else
|
58
73
|
join_attributes
|
59
74
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/enumerable"
|
2
4
|
require "active_support/core_ext/string/conversions"
|
3
5
|
require "active_support/core_ext/module/remove_method"
|
@@ -138,26 +140,6 @@ module ActiveRecord
|
|
138
140
|
class HasOneThroughCantAssociateThroughHasOneOrManyReflection < ThroughCantAssociateThroughHasOneOrManyReflection #:nodoc:
|
139
141
|
end
|
140
142
|
|
141
|
-
class HasManyThroughCantAssociateNewRecords < ActiveRecordError #:nodoc:
|
142
|
-
def initialize(owner = nil, reflection = nil)
|
143
|
-
if owner && reflection
|
144
|
-
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.")
|
145
|
-
else
|
146
|
-
super("Cannot associate new records.")
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
class HasManyThroughCantDissociateNewRecords < ActiveRecordError #:nodoc:
|
152
|
-
def initialize(owner = nil, reflection = nil)
|
153
|
-
if owner && reflection
|
154
|
-
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.")
|
155
|
-
else
|
156
|
-
super("Cannot dissociate new records.")
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
143
|
class ThroughNestedAssociationsAreReadonly < ActiveRecordError #:nodoc:
|
162
144
|
def initialize(owner = nil, reflection = nil)
|
163
145
|
if owner && reflection
|
@@ -187,16 +169,6 @@ module ActiveRecord
|
|
187
169
|
end
|
188
170
|
end
|
189
171
|
|
190
|
-
class ReadOnlyAssociation < ActiveRecordError #:nodoc:
|
191
|
-
def initialize(reflection = nil)
|
192
|
-
if reflection
|
193
|
-
super("Cannot add to a has_many :through association. Try adding to #{reflection.through_reflection.name.inspect}.")
|
194
|
-
else
|
195
|
-
super("Read-only reflection error.")
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
172
|
# This error is raised when trying to destroy a parent instance in N:1 or 1:1 associations
|
201
173
|
# (has_many, has_one) when there is at least 1 child associated instance.
|
202
174
|
# ex: if @project.tasks.size > 0, DeleteRestrictionError will be raised when trying to destroy @project
|
@@ -481,14 +453,14 @@ module ActiveRecord
|
|
481
453
|
# The tables for these classes could look something like:
|
482
454
|
#
|
483
455
|
# CREATE TABLE users (
|
484
|
-
# id
|
485
|
-
# account_id
|
456
|
+
# id bigint NOT NULL auto_increment,
|
457
|
+
# account_id bigint default NULL,
|
486
458
|
# name varchar default NULL,
|
487
459
|
# PRIMARY KEY (id)
|
488
460
|
# )
|
489
461
|
#
|
490
462
|
# CREATE TABLE accounts (
|
491
|
-
# id
|
463
|
+
# id bigint NOT NULL auto_increment,
|
492
464
|
# name varchar default NULL,
|
493
465
|
# PRIMARY KEY (id)
|
494
466
|
# )
|
@@ -555,9 +527,8 @@ module ActiveRecord
|
|
555
527
|
# has_many :birthday_events, ->(user) { where(starts_on: user.birthday) }, class_name: 'Event'
|
556
528
|
# end
|
557
529
|
#
|
558
|
-
# Note: Joining, eager loading and preloading of these associations is not
|
530
|
+
# Note: Joining, eager loading and preloading of these associations is not possible.
|
559
531
|
# These operations happen before instance creation and the scope will be called with a +nil+ argument.
|
560
|
-
# This can lead to unexpected behavior and is deprecated.
|
561
532
|
#
|
562
533
|
# == Association callbacks
|
563
534
|
#
|
@@ -848,7 +819,7 @@ module ActiveRecord
|
|
848
819
|
# project.milestones # fetches milestones from the database
|
849
820
|
# project.milestones.size # uses the milestone cache
|
850
821
|
# project.milestones.empty? # uses the milestone cache
|
851
|
-
# project.milestones
|
822
|
+
# project.milestones.reload.size # fetches milestones from the database
|
852
823
|
# project.milestones # uses the milestone cache
|
853
824
|
#
|
854
825
|
# == Eager loading of associations
|
@@ -1090,12 +1061,6 @@ module ActiveRecord
|
|
1090
1061
|
# belongs_to :dungeon, inverse_of: :evil_wizard
|
1091
1062
|
# end
|
1092
1063
|
#
|
1093
|
-
# There are limitations to <tt>:inverse_of</tt> support:
|
1094
|
-
#
|
1095
|
-
# * does not work with <tt>:through</tt> associations.
|
1096
|
-
# * does not work with <tt>:polymorphic</tt> associations.
|
1097
|
-
# * inverse associations for #belongs_to associations #has_many are ignored.
|
1098
|
-
#
|
1099
1064
|
# For more information, see the documentation for the +:inverse_of+ option.
|
1100
1065
|
#
|
1101
1066
|
# == Deleting from associations
|
@@ -1189,7 +1154,7 @@ module ActiveRecord
|
|
1189
1154
|
# +collection+ is a placeholder for the symbol passed as the +name+ argument, so
|
1190
1155
|
# <tt>has_many :clients</tt> would add among others <tt>clients.empty?</tt>.
|
1191
1156
|
#
|
1192
|
-
# [collection
|
1157
|
+
# [collection]
|
1193
1158
|
# Returns a Relation of all the associated objects.
|
1194
1159
|
# An empty Relation is returned if none are found.
|
1195
1160
|
# [collection<<(object, ...)]
|
@@ -1308,6 +1273,9 @@ module ActiveRecord
|
|
1308
1273
|
# Specify the foreign key used for the association. By default this is guessed to be the name
|
1309
1274
|
# of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_many
|
1310
1275
|
# association will use "person_id" as the default <tt>:foreign_key</tt>.
|
1276
|
+
#
|
1277
|
+
# If you are going to modify the association (rather than just read from it), then it is
|
1278
|
+
# a good idea to set the <tt>:inverse_of</tt> option.
|
1311
1279
|
# [:foreign_type]
|
1312
1280
|
# Specify the column used to store the associated object's type, if this is a polymorphic
|
1313
1281
|
# association. By default this is guessed to be the name of the polymorphic association
|
@@ -1381,8 +1349,7 @@ module ActiveRecord
|
|
1381
1349
|
# <tt>:autosave</tt> to <tt>true</tt>.
|
1382
1350
|
# [:inverse_of]
|
1383
1351
|
# Specifies the name of the #belongs_to association on the associated object
|
1384
|
-
# that is the inverse of this #has_many association.
|
1385
|
-
# with <tt>:through</tt> or <tt>:as</tt> options.
|
1352
|
+
# that is the inverse of this #has_many association.
|
1386
1353
|
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
|
1387
1354
|
# [:extend]
|
1388
1355
|
# Specifies a module or array of modules that will be extended into the association object returned.
|
@@ -1398,7 +1365,7 @@ module ActiveRecord
|
|
1398
1365
|
# has_many :tags, as: :taggable
|
1399
1366
|
# has_many :reports, -> { readonly }
|
1400
1367
|
# has_many :subscribers, through: :subscriptions, source: :user
|
1401
|
-
def has_many(name, scope = nil, options
|
1368
|
+
def has_many(name, scope = nil, **options, &extension)
|
1402
1369
|
reflection = Builder::HasMany.build(self, name, scope, options, &extension)
|
1403
1370
|
Reflection.add_reflection self, name, reflection
|
1404
1371
|
end
|
@@ -1478,6 +1445,9 @@ module ActiveRecord
|
|
1478
1445
|
# Specify the foreign key used for the association. By default this is guessed to be the name
|
1479
1446
|
# of this class in lower-case and "_id" suffixed. So a Person class that makes a #has_one association
|
1480
1447
|
# will use "person_id" as the default <tt>:foreign_key</tt>.
|
1448
|
+
#
|
1449
|
+
# If you are going to modify the association (rather than just read from it), then it is
|
1450
|
+
# a good idea to set the <tt>:inverse_of</tt> option.
|
1481
1451
|
# [:foreign_type]
|
1482
1452
|
# Specify the column used to store the associated object's type, if this is a polymorphic
|
1483
1453
|
# association. By default this is guessed to be the name of the polymorphic association
|
@@ -1493,6 +1463,9 @@ module ActiveRecord
|
|
1493
1463
|
# <tt>:primary_key</tt>, and <tt>:foreign_key</tt> are ignored, as the association uses the
|
1494
1464
|
# source reflection. You can only use a <tt>:through</tt> query through a #has_one
|
1495
1465
|
# or #belongs_to association on the join model.
|
1466
|
+
#
|
1467
|
+
# If you are going to modify the association (rather than just read from it), then it is
|
1468
|
+
# a good idea to set the <tt>:inverse_of</tt> option.
|
1496
1469
|
# [:source]
|
1497
1470
|
# Specifies the source association name used by #has_one <tt>:through</tt> queries.
|
1498
1471
|
# Only use it if the name cannot be inferred from the association.
|
@@ -1513,8 +1486,7 @@ module ActiveRecord
|
|
1513
1486
|
# <tt>:autosave</tt> to <tt>true</tt>.
|
1514
1487
|
# [:inverse_of]
|
1515
1488
|
# Specifies the name of the #belongs_to association on the associated object
|
1516
|
-
# that is the inverse of this #has_one association.
|
1517
|
-
# with <tt>:through</tt> or <tt>:as</tt> options.
|
1489
|
+
# that is the inverse of this #has_one association.
|
1518
1490
|
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
|
1519
1491
|
# [:required]
|
1520
1492
|
# When set to +true+, the association will also have its presence validated.
|
@@ -1532,7 +1504,7 @@ module ActiveRecord
|
|
1532
1504
|
# has_one :club, through: :membership
|
1533
1505
|
# has_one :primary_address, -> { where(primary: true) }, through: :addressables, source: :addressable
|
1534
1506
|
# has_one :credit_card, required: true
|
1535
|
-
def has_one(name, scope = nil, options
|
1507
|
+
def has_one(name, scope = nil, **options)
|
1536
1508
|
reflection = Builder::HasOne.build(self, name, scope, options)
|
1537
1509
|
Reflection.add_reflection self, name, reflection
|
1538
1510
|
end
|
@@ -1599,6 +1571,9 @@ module ActiveRecord
|
|
1599
1571
|
# association will use "person_id" as the default <tt>:foreign_key</tt>. Similarly,
|
1600
1572
|
# <tt>belongs_to :favorite_person, class_name: "Person"</tt> will use a foreign key
|
1601
1573
|
# of "favorite_person_id".
|
1574
|
+
#
|
1575
|
+
# If you are going to modify the association (rather than just read from it), then it is
|
1576
|
+
# a good idea to set the <tt>:inverse_of</tt> option.
|
1602
1577
|
# [:foreign_type]
|
1603
1578
|
# Specify the column used to store the associated object's type, if this is a polymorphic
|
1604
1579
|
# association. By default this is guessed to be the name of the association with a "_type"
|
@@ -1648,8 +1623,7 @@ module ActiveRecord
|
|
1648
1623
|
# +after_commit+ and +after_rollback+ callbacks are executed.
|
1649
1624
|
# [:inverse_of]
|
1650
1625
|
# Specifies the name of the #has_one or #has_many association on the associated
|
1651
|
-
# object that is the inverse of this #belongs_to association.
|
1652
|
-
# combination with the <tt>:polymorphic</tt> options.
|
1626
|
+
# object that is the inverse of this #belongs_to association.
|
1653
1627
|
# See ActiveRecord::Associations::ClassMethods's overview on Bi-directional associations for more detail.
|
1654
1628
|
# [:optional]
|
1655
1629
|
# When set to +true+, the association will not have its presence validated.
|
@@ -1676,7 +1650,7 @@ module ActiveRecord
|
|
1676
1650
|
# belongs_to :company, touch: :employees_last_updated_at
|
1677
1651
|
# belongs_to :user, optional: true
|
1678
1652
|
# belongs_to :account, default: -> { company.account }
|
1679
|
-
def belongs_to(name, scope = nil, options
|
1653
|
+
def belongs_to(name, scope = nil, **options)
|
1680
1654
|
reflection = Builder::BelongsTo.build(self, name, scope, options)
|
1681
1655
|
Reflection.add_reflection self, name, reflection
|
1682
1656
|
end
|
@@ -1818,6 +1792,9 @@ module ActiveRecord
|
|
1818
1792
|
# of this class in lower-case and "_id" suffixed. So a Person class that makes
|
1819
1793
|
# a #has_and_belongs_to_many association to Project will use "person_id" as the
|
1820
1794
|
# default <tt>:foreign_key</tt>.
|
1795
|
+
#
|
1796
|
+
# If you are going to modify the association (rather than just read from it), then it is
|
1797
|
+
# a good idea to set the <tt>:inverse_of</tt> option.
|
1821
1798
|
# [:association_foreign_key]
|
1822
1799
|
# Specify the foreign key used for the association on the receiving side of the association.
|
1823
1800
|
# By default this is guessed to be the name of the associated class in lower-case and "_id" suffixed.
|
@@ -1846,7 +1823,7 @@ module ActiveRecord
|
|
1846
1823
|
|
1847
1824
|
builder = Builder::HasAndBelongsToMany.new name, self, options
|
1848
1825
|
|
1849
|
-
join_model =
|
1826
|
+
join_model = builder.through_model
|
1850
1827
|
|
1851
1828
|
const_set join_model.name, join_model
|
1852
1829
|
private_constant join_model.name
|
@@ -1875,7 +1852,7 @@ module ActiveRecord
|
|
1875
1852
|
hm_options[k] = options[k] if options.key? k
|
1876
1853
|
end
|
1877
1854
|
|
1878
|
-
|
1855
|
+
has_many name, scope, hm_options, &extension
|
1879
1856
|
_reflections[name.to_s].parent_reflection = habtm_reflection
|
1880
1857
|
end
|
1881
1858
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_model/forbidden_attributes_protection"
|
2
4
|
|
3
5
|
module ActiveRecord
|
@@ -5,11 +7,6 @@ module ActiveRecord
|
|
5
7
|
extend ActiveSupport::Concern
|
6
8
|
include ActiveModel::AttributeAssignment
|
7
9
|
|
8
|
-
# Alias for ActiveModel::AttributeAssignment#assign_attributes. See ActiveModel::AttributeAssignment.
|
9
|
-
def attributes=(attributes)
|
10
|
-
assign_attributes(attributes)
|
11
|
-
end
|
12
|
-
|
13
10
|
private
|
14
11
|
|
15
12
|
def _assign_attributes(attributes)
|
@@ -1,10 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module AttributeDecorators # :nodoc:
|
3
5
|
extend ActiveSupport::Concern
|
4
6
|
|
5
7
|
included do
|
6
|
-
class_attribute :attribute_type_decorations, instance_accessor: false # :internal:
|
7
|
-
self.attribute_type_decorations = TypeDecorator.new
|
8
|
+
class_attribute :attribute_type_decorations, instance_accessor: false, default: TypeDecorator.new # :internal:
|
8
9
|
end
|
9
10
|
|
10
11
|
module ClassMethods # :nodoc:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "active_support/core_ext/module/attribute_accessors"
|
3
|
-
require "active_record/attribute_mutation_tracker"
|
4
4
|
|
5
5
|
module ActiveRecord
|
6
6
|
module AttributeMethods
|
@@ -14,11 +14,10 @@ module ActiveRecord
|
|
14
14
|
raise "You cannot include Dirty after Timestamp"
|
15
15
|
end
|
16
16
|
|
17
|
-
class_attribute :partial_writes, instance_writer: false
|
18
|
-
self.partial_writes = true
|
17
|
+
class_attribute :partial_writes, instance_writer: false, default: true
|
19
18
|
|
20
|
-
after_create {
|
21
|
-
after_update {
|
19
|
+
after_create { changes_applied }
|
20
|
+
after_update { changes_applied }
|
22
21
|
|
23
22
|
# Attribute methods for "changed in last call to save?"
|
24
23
|
attribute_method_affix(prefix: "saved_change_to_", suffix: "?")
|
@@ -30,107 +29,18 @@ module ActiveRecord
|
|
30
29
|
attribute_method_suffix("_change_to_be_saved", "_in_database")
|
31
30
|
end
|
32
31
|
|
33
|
-
# Attempts to +save+ the record and clears changed attributes if successful.
|
34
|
-
def save(*)
|
35
|
-
if status = super
|
36
|
-
changes_applied
|
37
|
-
end
|
38
|
-
status
|
39
|
-
end
|
40
|
-
|
41
|
-
# Attempts to <tt>save!</tt> the record and clears changed attributes if successful.
|
42
|
-
def save!(*)
|
43
|
-
super.tap do
|
44
|
-
changes_applied
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
32
|
# <tt>reload</tt> the record and clears changed attributes.
|
49
33
|
def reload(*)
|
50
34
|
super.tap do
|
51
|
-
@
|
52
|
-
|
53
|
-
@
|
54
|
-
|
55
|
-
end
|
56
|
-
|
57
|
-
def initialize_dup(other) # :nodoc:
|
58
|
-
super
|
59
|
-
@attributes = self.class._default_attributes.map do |attr|
|
60
|
-
attr.with_value_from_user(@attributes.fetch_value(attr.name))
|
61
|
-
end
|
62
|
-
clear_mutation_trackers
|
63
|
-
end
|
64
|
-
|
65
|
-
def changes_internally_applied # :nodoc:
|
66
|
-
@mutations_before_last_save = mutations_from_database
|
67
|
-
forget_attribute_assignments
|
68
|
-
@mutations_from_database = AttributeMutationTracker.new(@attributes)
|
69
|
-
end
|
70
|
-
|
71
|
-
def changes_applied # :nodoc:
|
72
|
-
@previous_mutation_tracker = mutation_tracker
|
73
|
-
@changed_attributes = ActiveSupport::HashWithIndifferentAccess.new
|
74
|
-
@mutation_tracker = nil
|
75
|
-
@mutations_from_database = nil
|
76
|
-
end
|
77
|
-
|
78
|
-
def clear_changes_information # :nodoc:
|
79
|
-
@previous_mutation_tracker = nil
|
80
|
-
@changed_attributes = ActiveSupport::HashWithIndifferentAccess.new
|
81
|
-
forget_attribute_assignments
|
82
|
-
clear_mutation_trackers
|
83
|
-
end
|
84
|
-
|
85
|
-
def raw_write_attribute(attr_name, *) # :nodoc:
|
86
|
-
result = super
|
87
|
-
clear_attribute_change(attr_name)
|
88
|
-
result
|
89
|
-
end
|
90
|
-
|
91
|
-
def clear_attribute_changes(attr_names) # :nodoc:
|
92
|
-
super
|
93
|
-
attr_names.each do |attr_name|
|
94
|
-
clear_attribute_change(attr_name)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def changed_attributes # :nodoc:
|
99
|
-
# This should only be set by methods which will call changed_attributes
|
100
|
-
# multiple times when it is known that the computed value cannot change.
|
101
|
-
if defined?(@cached_changed_attributes)
|
102
|
-
@cached_changed_attributes
|
103
|
-
else
|
104
|
-
emit_warning_if_needed("changed_attributes", "saved_changes.transform_values(&:first)")
|
105
|
-
super.reverse_merge(mutation_tracker.changed_values).freeze
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
def changes # :nodoc:
|
110
|
-
cache_changed_attributes do
|
111
|
-
emit_warning_if_needed("changes", "saved_changes")
|
112
|
-
super
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
def previous_changes # :nodoc:
|
117
|
-
unless previous_mutation_tracker.equal?(mutations_before_last_save)
|
118
|
-
ActiveSupport::Deprecation.warn(<<-EOW.strip_heredoc)
|
119
|
-
The behavior of `previous_changes` inside of after callbacks is
|
120
|
-
deprecated without replacement. In the next release of Rails,
|
121
|
-
this method inside of `after_save` will return the changes that
|
122
|
-
were just saved.
|
123
|
-
EOW
|
35
|
+
@previously_changed = ActiveSupport::HashWithIndifferentAccess.new
|
36
|
+
@mutations_before_last_save = nil
|
37
|
+
@attributes_changed_by_setter = ActiveSupport::HashWithIndifferentAccess.new
|
38
|
+
@mutations_from_database = nil
|
124
39
|
end
|
125
|
-
previous_mutation_tracker.changes
|
126
|
-
end
|
127
|
-
|
128
|
-
def attribute_changed_in_place?(attr_name) # :nodoc:
|
129
|
-
mutation_tracker.changed_in_place?(attr_name)
|
130
40
|
end
|
131
41
|
|
132
42
|
# Did this attribute change when we last saved? This method can be invoked
|
133
|
-
# as
|
43
|
+
# as +saved_change_to_name?+ instead of <tt>saved_change_to_attribute?("name")</tt>.
|
134
44
|
# Behaves similarly to +attribute_changed?+. This method is useful in
|
135
45
|
# after callbacks to determine if the call to save changed a certain
|
136
46
|
# attribute.
|
@@ -153,8 +63,8 @@ module ActiveRecord
|
|
153
63
|
# Behaves similarly to +attribute_change+. This method is useful in after
|
154
64
|
# callbacks, to see the change in an attribute that just occurred
|
155
65
|
#
|
156
|
-
# This method can be invoked as
|
157
|
-
#
|
66
|
+
# This method can be invoked as +saved_change_to_name+ in instead of
|
67
|
+
# <tt>saved_change_to_attribute("name")</tt>
|
158
68
|
def saved_change_to_attribute(attr_name)
|
159
69
|
mutations_before_last_save.change_to_attribute(attr_name)
|
160
70
|
end
|
@@ -167,7 +77,7 @@ module ActiveRecord
|
|
167
77
|
mutations_before_last_save.original_value(attr_name)
|
168
78
|
end
|
169
79
|
|
170
|
-
# Did the last call to
|
80
|
+
# Did the last call to +save+ have any changes to change?
|
171
81
|
def saved_changes?
|
172
82
|
mutations_before_last_save.any_changes?
|
173
83
|
end
|
@@ -177,116 +87,46 @@ module ActiveRecord
|
|
177
87
|
mutations_before_last_save.changes
|
178
88
|
end
|
179
89
|
|
180
|
-
# Alias for
|
90
|
+
# Alias for +attribute_changed?+
|
181
91
|
def will_save_change_to_attribute?(attr_name, **options)
|
182
92
|
mutations_from_database.changed?(attr_name, **options)
|
183
93
|
end
|
184
94
|
|
185
|
-
# Alias for
|
95
|
+
# Alias for +attribute_change+
|
186
96
|
def attribute_change_to_be_saved(attr_name)
|
187
97
|
mutations_from_database.change_to_attribute(attr_name)
|
188
98
|
end
|
189
99
|
|
190
|
-
# Alias for
|
100
|
+
# Alias for +attribute_was+
|
191
101
|
def attribute_in_database(attr_name)
|
192
102
|
mutations_from_database.original_value(attr_name)
|
193
103
|
end
|
194
104
|
|
195
|
-
# Alias for
|
105
|
+
# Alias for +changed?+
|
196
106
|
def has_changes_to_save?
|
197
107
|
mutations_from_database.any_changes?
|
198
108
|
end
|
199
109
|
|
200
|
-
# Alias for
|
110
|
+
# Alias for +changes+
|
201
111
|
def changes_to_save
|
202
112
|
mutations_from_database.changes
|
203
113
|
end
|
204
114
|
|
205
|
-
# Alias for
|
115
|
+
# Alias for +changed+
|
206
116
|
def changed_attribute_names_to_save
|
207
|
-
|
117
|
+
changes_to_save.keys
|
208
118
|
end
|
209
119
|
|
210
|
-
# Alias for
|
120
|
+
# Alias for +changed_attributes+
|
211
121
|
def attributes_in_database
|
212
|
-
|
213
|
-
end
|
214
|
-
|
215
|
-
def attribute_was(*)
|
216
|
-
emit_warning_if_needed("attribute_was", "attribute_before_last_save")
|
217
|
-
super
|
218
|
-
end
|
219
|
-
|
220
|
-
def attribute_change(*)
|
221
|
-
emit_warning_if_needed("attribute_change", "saved_change_to_attribute")
|
222
|
-
super
|
223
|
-
end
|
224
|
-
|
225
|
-
def attribute_changed?(*)
|
226
|
-
emit_warning_if_needed("attribute_changed?", "saved_change_to_attribute?")
|
227
|
-
super
|
228
|
-
end
|
229
|
-
|
230
|
-
def changed?(*)
|
231
|
-
emit_warning_if_needed("changed?", "saved_changes?")
|
232
|
-
super
|
233
|
-
end
|
234
|
-
|
235
|
-
def changed(*)
|
236
|
-
emit_warning_if_needed("changed", "saved_changes.keys")
|
237
|
-
super
|
122
|
+
changes_to_save.transform_values(&:first)
|
238
123
|
end
|
239
124
|
|
240
125
|
private
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
end
|
246
|
-
@mutation_tracker ||= AttributeMutationTracker.new(@attributes)
|
247
|
-
end
|
248
|
-
|
249
|
-
def emit_warning_if_needed(method_name, new_method_name)
|
250
|
-
unless mutation_tracker.equal?(mutations_from_database)
|
251
|
-
ActiveSupport::Deprecation.warn(<<-EOW.squish)
|
252
|
-
The behavior of `#{method_name}` inside of after callbacks will
|
253
|
-
be changing in the next version of Rails. The new return value will reflect the
|
254
|
-
behavior of calling the method after `save` returned (e.g. the opposite of what
|
255
|
-
it returns now). To maintain the current behavior, use `#{new_method_name}`
|
256
|
-
instead.
|
257
|
-
EOW
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
def mutations_from_database
|
262
|
-
unless defined?(@mutations_from_database)
|
263
|
-
@mutations_from_database = nil
|
264
|
-
end
|
265
|
-
@mutations_from_database ||= mutation_tracker
|
266
|
-
end
|
267
|
-
|
268
|
-
def changes_include?(attr_name)
|
269
|
-
super || mutation_tracker.changed?(attr_name)
|
270
|
-
end
|
271
|
-
|
272
|
-
def clear_attribute_change(attr_name)
|
273
|
-
mutation_tracker.forget_change(attr_name)
|
274
|
-
mutations_from_database.forget_change(attr_name)
|
275
|
-
end
|
276
|
-
|
277
|
-
def attribute_will_change!(attr_name)
|
278
|
-
super
|
279
|
-
if self.class.has_attribute?(attr_name)
|
280
|
-
mutations_from_database.force_change(attr_name)
|
281
|
-
else
|
282
|
-
ActiveSupport::Deprecation.warn(<<-EOW.squish)
|
283
|
-
#{attr_name} is not an attribute known to Active Record.
|
284
|
-
This behavior is deprecated and will be removed in the next
|
285
|
-
version of Rails. If you'd like #{attr_name} to be managed
|
286
|
-
by Active Record, add `attribute :#{attr_name} to your class.
|
287
|
-
EOW
|
288
|
-
mutations_from_database.deprecated_force_change(attr_name)
|
289
|
-
end
|
126
|
+
def write_attribute_without_type_cast(attr_name, _)
|
127
|
+
result = super
|
128
|
+
clear_attribute_change(attr_name)
|
129
|
+
result
|
290
130
|
end
|
291
131
|
|
292
132
|
def _update_record(*)
|
@@ -300,35 +140,6 @@ module ActiveRecord
|
|
300
140
|
def keys_for_partial_write
|
301
141
|
changed_attribute_names_to_save & self.class.column_names
|
302
142
|
end
|
303
|
-
|
304
|
-
def forget_attribute_assignments
|
305
|
-
@attributes = @attributes.map(&:forgetting_assignment)
|
306
|
-
end
|
307
|
-
|
308
|
-
def clear_mutation_trackers
|
309
|
-
@mutation_tracker = nil
|
310
|
-
@mutations_from_database = nil
|
311
|
-
@mutations_before_last_save = nil
|
312
|
-
end
|
313
|
-
|
314
|
-
def previous_mutation_tracker
|
315
|
-
@previous_mutation_tracker ||= NullMutationTracker.instance
|
316
|
-
end
|
317
|
-
|
318
|
-
def mutations_before_last_save
|
319
|
-
@mutations_before_last_save ||= previous_mutation_tracker
|
320
|
-
end
|
321
|
-
|
322
|
-
def cache_changed_attributes
|
323
|
-
@cached_changed_attributes = changed_attributes
|
324
|
-
yield
|
325
|
-
ensure
|
326
|
-
clear_changed_attributes_cache
|
327
|
-
end
|
328
|
-
|
329
|
-
def clear_changed_attributes_cache
|
330
|
-
remove_instance_variable(:@cached_changed_attributes) if defined?(@cached_changed_attributes)
|
331
|
-
end
|
332
143
|
end
|
333
144
|
end
|
334
145
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "set"
|
2
4
|
|
3
5
|
module ActiveRecord
|
@@ -8,23 +10,22 @@ module ActiveRecord
|
|
8
10
|
# Returns this record's primary key value wrapped in an array if one is
|
9
11
|
# available.
|
10
12
|
def to_key
|
11
|
-
sync_with_transaction_state
|
12
13
|
key = id
|
13
14
|
[key] if key
|
14
15
|
end
|
15
16
|
|
16
17
|
# Returns the primary key value.
|
17
18
|
def id
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
19
|
+
sync_with_transaction_state
|
20
|
+
primary_key = self.class.primary_key
|
21
|
+
_read_attribute(primary_key) if primary_key
|
22
22
|
end
|
23
23
|
|
24
24
|
# Sets the primary key value.
|
25
25
|
def id=(value)
|
26
26
|
sync_with_transaction_state
|
27
|
-
|
27
|
+
primary_key = self.class.primary_key
|
28
|
+
_write_attribute(primary_key, value) if primary_key
|
28
29
|
end
|
29
30
|
|
30
31
|
# Queries the primary key value.
|