activerecord 5.1.6.2 → 5.2.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +635 -650
- 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 +7 -5
- data/lib/active_record/associations/alias_tracker.rb +19 -27
- data/lib/active_record/associations/association.rb +41 -37
- data/lib/active_record/associations/association_scope.rb +38 -50
- data/lib/active_record/associations/belongs_to_association.rb +28 -9
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
- data/lib/active_record/associations/builder/association.rb +4 -7
- data/lib/active_record/associations/builder/belongs_to.rb +14 -5
- data/lib/active_record/associations/builder/collection_association.rb +3 -3
- 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 +59 -47
- data/lib/active_record/associations/collection_proxy.rb +20 -49
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +12 -1
- data/lib/active_record/associations/has_many_through_association.rb +36 -30
- data/lib/active_record/associations/has_one_association.rb +12 -1
- data/lib/active_record/associations/has_one_through_association.rb +13 -8
- data/lib/active_record/associations/join_dependency/join_association.rb +39 -63
- data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +9 -9
- data/lib/active_record/associations/join_dependency.rb +48 -93
- 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 +18 -38
- data/lib/active_record/associations/singular_association.rb +14 -16
- data/lib/active_record/associations/through_association.rb +26 -11
- data/lib/active_record/associations.rb +40 -63
- 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 +32 -216
- 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 +9 -3
- 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 +35 -19
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +12 -6
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +15 -1
- data/lib/active_record/collection_cache_key.rb +12 -8
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +142 -42
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +174 -33
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +15 -5
- data/lib/active_record/connection_adapters/abstract/quoting.rb +14 -31
- 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 +64 -6
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +152 -81
- data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -21
- data/lib/active_record/connection_adapters/abstract_adapter.rb +84 -97
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +110 -173
- 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 +13 -2
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +47 -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 +13 -1
- 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 +5 -3
- 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 +8 -2
- 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 +50 -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 +233 -111
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +66 -74
- 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 +23 -0
- 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 +75 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +82 -95
- 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 +51 -61
- data/lib/active_record/counter_cache.rb +20 -15
- data/lib/active_record/define_callbacks.rb +5 -3
- data/lib/active_record/dynamic_matchers.rb +9 -9
- data/lib/active_record/enum.rb +18 -13
- data/lib/active_record/errors.rb +60 -15
- 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 +5 -3
- 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 +47 -9
- 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 +169 -17
- data/lib/active_record/query_cache.rb +6 -8
- data/lib/active_record/querying.rb +4 -2
- data/lib/active_record/railtie.rb +80 -6
- 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 +108 -194
- 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 +45 -19
- data/lib/active_record/relation/delegation.rb +45 -27
- data/lib/active_record/relation/finder_methods.rb +77 -78
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +53 -23
- 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 +60 -79
- data/lib/active_record/relation/query_attribute.rb +28 -2
- data/lib/active_record/relation/query_methods.rb +129 -100
- data/lib/active_record/relation/record_fetch_warning.rb +2 -0
- data/lib/active_record/relation/spawn_methods.rb +4 -2
- 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 +120 -214
- 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 +8 -9
- data/lib/active_record/scoping/named.rb +23 -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 +23 -13
- 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 +13 -6
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +33 -28
- 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 +6 -0
- 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/migration/migration_generator.rb +3 -1
- 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.rb +3 -1
- metadata +26 -39
- 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 -114
- 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
- /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/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/model/templates/{model.rb → model.rb.tt} +0 -0
- /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -1,15 +0,0 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module Associations
|
3
|
-
class Preloader
|
4
|
-
class HasOne < SingularAssociation #:nodoc:
|
5
|
-
def association_key_name
|
6
|
-
reflection.foreign_key
|
7
|
-
end
|
8
|
-
|
9
|
-
def owner_key_name
|
10
|
-
reflection.active_record_primary_key
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module Associations
|
3
|
-
class Preloader
|
4
|
-
class SingularAssociation < Association #:nodoc:
|
5
|
-
private
|
6
|
-
|
7
|
-
def preload(preloader)
|
8
|
-
associated_records_by_owner(preloader).each do |owner, associated_records|
|
9
|
-
record = associated_records.first
|
10
|
-
|
11
|
-
association = owner.association(reflection.name)
|
12
|
-
association.target = record
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
require "active_record/attribute"
|
2
|
-
|
3
|
-
module ActiveRecord
|
4
|
-
class Attribute # :nodoc:
|
5
|
-
class UserProvidedDefault < FromUser # :nodoc:
|
6
|
-
def initialize(name, value, type, database_default)
|
7
|
-
@user_provided_value = value
|
8
|
-
super(name, value, type, database_default)
|
9
|
-
end
|
10
|
-
|
11
|
-
def value_before_type_cast
|
12
|
-
if user_provided_value.is_a?(Proc)
|
13
|
-
@memoized_value_before_type_cast ||= user_provided_value.call
|
14
|
-
else
|
15
|
-
@user_provided_value
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def with_type(type)
|
20
|
-
self.class.new(name, user_provided_value, type, original_attribute)
|
21
|
-
end
|
22
|
-
|
23
|
-
# TODO Change this to private once we've dropped Ruby 2.2 support.
|
24
|
-
# Workaround for Ruby 2.2 "private attribute?" warning.
|
25
|
-
protected
|
26
|
-
|
27
|
-
attr_reader :user_provided_value
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,240 +0,0 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
class Attribute # :nodoc:
|
3
|
-
class << self
|
4
|
-
def from_database(name, value, type)
|
5
|
-
FromDatabase.new(name, value, type)
|
6
|
-
end
|
7
|
-
|
8
|
-
def from_user(name, value, type, original_attribute = nil)
|
9
|
-
FromUser.new(name, value, type, original_attribute)
|
10
|
-
end
|
11
|
-
|
12
|
-
def with_cast_value(name, value, type)
|
13
|
-
WithCastValue.new(name, value, type)
|
14
|
-
end
|
15
|
-
|
16
|
-
def null(name)
|
17
|
-
Null.new(name)
|
18
|
-
end
|
19
|
-
|
20
|
-
def uninitialized(name, type)
|
21
|
-
Uninitialized.new(name, type)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
attr_reader :name, :value_before_type_cast, :type
|
26
|
-
|
27
|
-
# This method should not be called directly.
|
28
|
-
# Use #from_database or #from_user
|
29
|
-
def initialize(name, value_before_type_cast, type, original_attribute = nil)
|
30
|
-
@name = name
|
31
|
-
@value_before_type_cast = value_before_type_cast
|
32
|
-
@type = type
|
33
|
-
@original_attribute = original_attribute
|
34
|
-
end
|
35
|
-
|
36
|
-
def value
|
37
|
-
# `defined?` is cheaper than `||=` when we get back falsy values
|
38
|
-
@value = type_cast(value_before_type_cast) unless defined?(@value)
|
39
|
-
@value
|
40
|
-
end
|
41
|
-
|
42
|
-
def original_value
|
43
|
-
if assigned?
|
44
|
-
original_attribute.original_value
|
45
|
-
else
|
46
|
-
type_cast(value_before_type_cast)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def value_for_database
|
51
|
-
type.serialize(value)
|
52
|
-
end
|
53
|
-
|
54
|
-
def changed?
|
55
|
-
changed_from_assignment? || changed_in_place?
|
56
|
-
end
|
57
|
-
|
58
|
-
def changed_in_place?
|
59
|
-
has_been_read? && type.changed_in_place?(original_value_for_database, value)
|
60
|
-
end
|
61
|
-
|
62
|
-
def forgetting_assignment
|
63
|
-
with_value_from_database(value_for_database)
|
64
|
-
end
|
65
|
-
|
66
|
-
def with_value_from_user(value)
|
67
|
-
type.assert_valid_value(value)
|
68
|
-
self.class.from_user(name, value, type, original_attribute || self)
|
69
|
-
end
|
70
|
-
|
71
|
-
def with_value_from_database(value)
|
72
|
-
self.class.from_database(name, value, type)
|
73
|
-
end
|
74
|
-
|
75
|
-
def with_cast_value(value)
|
76
|
-
self.class.with_cast_value(name, value, type)
|
77
|
-
end
|
78
|
-
|
79
|
-
def with_type(type)
|
80
|
-
if changed_in_place?
|
81
|
-
with_value_from_user(value).with_type(type)
|
82
|
-
else
|
83
|
-
self.class.new(name, value_before_type_cast, type, original_attribute)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def type_cast(*)
|
88
|
-
raise NotImplementedError
|
89
|
-
end
|
90
|
-
|
91
|
-
def initialized?
|
92
|
-
true
|
93
|
-
end
|
94
|
-
|
95
|
-
def came_from_user?
|
96
|
-
false
|
97
|
-
end
|
98
|
-
|
99
|
-
def has_been_read?
|
100
|
-
defined?(@value)
|
101
|
-
end
|
102
|
-
|
103
|
-
def ==(other)
|
104
|
-
self.class == other.class &&
|
105
|
-
name == other.name &&
|
106
|
-
value_before_type_cast == other.value_before_type_cast &&
|
107
|
-
type == other.type
|
108
|
-
end
|
109
|
-
alias eql? ==
|
110
|
-
|
111
|
-
def hash
|
112
|
-
[self.class, name, value_before_type_cast, type].hash
|
113
|
-
end
|
114
|
-
|
115
|
-
def init_with(coder)
|
116
|
-
@name = coder["name"]
|
117
|
-
@value_before_type_cast = coder["value_before_type_cast"]
|
118
|
-
@type = coder["type"]
|
119
|
-
@original_attribute = coder["original_attribute"]
|
120
|
-
@value = coder["value"] if coder.map.key?("value")
|
121
|
-
end
|
122
|
-
|
123
|
-
def encode_with(coder)
|
124
|
-
coder["name"] = name
|
125
|
-
coder["value_before_type_cast"] = value_before_type_cast unless value_before_type_cast.nil?
|
126
|
-
coder["type"] = type if type
|
127
|
-
coder["original_attribute"] = original_attribute if original_attribute
|
128
|
-
coder["value"] = value if defined?(@value)
|
129
|
-
end
|
130
|
-
|
131
|
-
# TODO Change this to private once we've dropped Ruby 2.2 support.
|
132
|
-
# Workaround for Ruby 2.2 "private attribute?" warning.
|
133
|
-
protected
|
134
|
-
|
135
|
-
attr_reader :original_attribute
|
136
|
-
alias_method :assigned?, :original_attribute
|
137
|
-
|
138
|
-
def original_value_for_database
|
139
|
-
if assigned?
|
140
|
-
original_attribute.original_value_for_database
|
141
|
-
else
|
142
|
-
_original_value_for_database
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
private
|
147
|
-
def initialize_dup(other)
|
148
|
-
if defined?(@value) && @value.duplicable?
|
149
|
-
@value = @value.dup
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
def changed_from_assignment?
|
154
|
-
assigned? && type.changed?(original_value, value, value_before_type_cast)
|
155
|
-
end
|
156
|
-
|
157
|
-
def _original_value_for_database
|
158
|
-
type.serialize(original_value)
|
159
|
-
end
|
160
|
-
|
161
|
-
class FromDatabase < Attribute # :nodoc:
|
162
|
-
def type_cast(value)
|
163
|
-
type.deserialize(value)
|
164
|
-
end
|
165
|
-
|
166
|
-
def _original_value_for_database
|
167
|
-
value_before_type_cast
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
class FromUser < Attribute # :nodoc:
|
172
|
-
def type_cast(value)
|
173
|
-
type.cast(value)
|
174
|
-
end
|
175
|
-
|
176
|
-
def came_from_user?
|
177
|
-
true
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
class WithCastValue < Attribute # :nodoc:
|
182
|
-
def type_cast(value)
|
183
|
-
value
|
184
|
-
end
|
185
|
-
|
186
|
-
def changed_in_place?
|
187
|
-
false
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
class Null < Attribute # :nodoc:
|
192
|
-
def initialize(name)
|
193
|
-
super(name, nil, Type.default_value)
|
194
|
-
end
|
195
|
-
|
196
|
-
def type_cast(*)
|
197
|
-
nil
|
198
|
-
end
|
199
|
-
|
200
|
-
def with_type(type)
|
201
|
-
self.class.with_cast_value(name, nil, type)
|
202
|
-
end
|
203
|
-
|
204
|
-
def with_value_from_database(value)
|
205
|
-
raise ActiveModel::MissingAttributeError, "can't write unknown attribute `#{name}`"
|
206
|
-
end
|
207
|
-
alias_method :with_value_from_user, :with_value_from_database
|
208
|
-
end
|
209
|
-
|
210
|
-
class Uninitialized < Attribute # :nodoc:
|
211
|
-
UNINITIALIZED_ORIGINAL_VALUE = Object.new
|
212
|
-
|
213
|
-
def initialize(name, type)
|
214
|
-
super(name, nil, type)
|
215
|
-
end
|
216
|
-
|
217
|
-
def value
|
218
|
-
if block_given?
|
219
|
-
yield name
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
def original_value
|
224
|
-
UNINITIALIZED_ORIGINAL_VALUE
|
225
|
-
end
|
226
|
-
|
227
|
-
def value_for_database
|
228
|
-
end
|
229
|
-
|
230
|
-
def initialized?
|
231
|
-
false
|
232
|
-
end
|
233
|
-
|
234
|
-
def with_type(type)
|
235
|
-
self.class.new(name, type)
|
236
|
-
end
|
237
|
-
end
|
238
|
-
private_constant :FromDatabase, :FromUser, :Null, :Uninitialized, :WithCastValue
|
239
|
-
end
|
240
|
-
end
|
@@ -1,114 +0,0 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
class AttributeMutationTracker # :nodoc:
|
3
|
-
OPTION_NOT_GIVEN = Object.new
|
4
|
-
|
5
|
-
def initialize(attributes)
|
6
|
-
@attributes = attributes
|
7
|
-
@forced_changes = Set.new
|
8
|
-
@deprecated_forced_changes = Set.new
|
9
|
-
end
|
10
|
-
|
11
|
-
def changed_values
|
12
|
-
attr_names.each_with_object({}.with_indifferent_access) do |attr_name, result|
|
13
|
-
if changed?(attr_name)
|
14
|
-
result[attr_name] = attributes[attr_name].original_value
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def changes
|
20
|
-
attr_names.each_with_object({}.with_indifferent_access) do |attr_name, result|
|
21
|
-
change = change_to_attribute(attr_name)
|
22
|
-
if change
|
23
|
-
result[attr_name] = change
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def change_to_attribute(attr_name)
|
29
|
-
attr_name = attr_name.to_s
|
30
|
-
if changed?(attr_name)
|
31
|
-
[attributes[attr_name].original_value, attributes.fetch_value(attr_name)]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def any_changes?
|
36
|
-
attr_names.any? { |attr| changed?(attr) } || deprecated_forced_changes.any?
|
37
|
-
end
|
38
|
-
|
39
|
-
def changed?(attr_name, from: OPTION_NOT_GIVEN, to: OPTION_NOT_GIVEN)
|
40
|
-
attr_name = attr_name.to_s
|
41
|
-
forced_changes.include?(attr_name) ||
|
42
|
-
attributes[attr_name].changed? &&
|
43
|
-
(OPTION_NOT_GIVEN == from || attributes[attr_name].original_value == from) &&
|
44
|
-
(OPTION_NOT_GIVEN == to || attributes[attr_name].value == to)
|
45
|
-
end
|
46
|
-
|
47
|
-
def changed_in_place?(attr_name)
|
48
|
-
attributes[attr_name.to_s].changed_in_place?
|
49
|
-
end
|
50
|
-
|
51
|
-
def forget_change(attr_name)
|
52
|
-
attr_name = attr_name.to_s
|
53
|
-
attributes[attr_name] = attributes[attr_name].forgetting_assignment
|
54
|
-
forced_changes.delete(attr_name)
|
55
|
-
end
|
56
|
-
|
57
|
-
def original_value(attr_name)
|
58
|
-
attributes[attr_name.to_s].original_value
|
59
|
-
end
|
60
|
-
|
61
|
-
def force_change(attr_name)
|
62
|
-
forced_changes << attr_name.to_s
|
63
|
-
end
|
64
|
-
|
65
|
-
def deprecated_force_change(attr_name)
|
66
|
-
deprecated_forced_changes << attr_name.to_s
|
67
|
-
end
|
68
|
-
|
69
|
-
# TODO Change this to private once we've dropped Ruby 2.2 support.
|
70
|
-
# Workaround for Ruby 2.2 "private attribute?" warning.
|
71
|
-
protected
|
72
|
-
|
73
|
-
attr_reader :attributes, :forced_changes, :deprecated_forced_changes
|
74
|
-
|
75
|
-
private
|
76
|
-
|
77
|
-
def attr_names
|
78
|
-
attributes.keys
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
class NullMutationTracker # :nodoc:
|
83
|
-
include Singleton
|
84
|
-
|
85
|
-
def changed_values(*)
|
86
|
-
{}
|
87
|
-
end
|
88
|
-
|
89
|
-
def changes(*)
|
90
|
-
{}
|
91
|
-
end
|
92
|
-
|
93
|
-
def change_to_attribute(attr_name)
|
94
|
-
end
|
95
|
-
|
96
|
-
def any_changes?(*)
|
97
|
-
false
|
98
|
-
end
|
99
|
-
|
100
|
-
def changed?(*)
|
101
|
-
false
|
102
|
-
end
|
103
|
-
|
104
|
-
def changed_in_place?(*)
|
105
|
-
false
|
106
|
-
end
|
107
|
-
|
108
|
-
def forget_change(*)
|
109
|
-
end
|
110
|
-
|
111
|
-
def original_value(*)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
@@ -1,126 +0,0 @@
|
|
1
|
-
require "active_record/attribute"
|
2
|
-
|
3
|
-
module ActiveRecord
|
4
|
-
class AttributeSet # :nodoc:
|
5
|
-
class Builder # :nodoc:
|
6
|
-
attr_reader :types, :default_attributes
|
7
|
-
|
8
|
-
def initialize(types, default_attributes = {})
|
9
|
-
@types = types
|
10
|
-
@default_attributes = default_attributes
|
11
|
-
end
|
12
|
-
|
13
|
-
def build_from_database(values = {}, additional_types = {})
|
14
|
-
attributes = LazyAttributeHash.new(types, values, additional_types, default_attributes)
|
15
|
-
AttributeSet.new(attributes)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
class LazyAttributeHash # :nodoc:
|
21
|
-
delegate :transform_values, :each_key, :each_value, :fetch, :except, to: :materialize
|
22
|
-
|
23
|
-
def initialize(types, values, additional_types, default_attributes, delegate_hash = {})
|
24
|
-
@types = types
|
25
|
-
@values = values
|
26
|
-
@additional_types = additional_types
|
27
|
-
@materialized = false
|
28
|
-
@delegate_hash = delegate_hash
|
29
|
-
@default_attributes = default_attributes
|
30
|
-
end
|
31
|
-
|
32
|
-
def key?(key)
|
33
|
-
delegate_hash.key?(key) || values.key?(key) || types.key?(key)
|
34
|
-
end
|
35
|
-
|
36
|
-
def [](key)
|
37
|
-
delegate_hash[key] || assign_default_value(key)
|
38
|
-
end
|
39
|
-
|
40
|
-
def []=(key, value)
|
41
|
-
if frozen?
|
42
|
-
raise RuntimeError, "Can't modify frozen hash"
|
43
|
-
end
|
44
|
-
delegate_hash[key] = value
|
45
|
-
end
|
46
|
-
|
47
|
-
def deep_dup
|
48
|
-
dup.tap do |copy|
|
49
|
-
copy.instance_variable_set(:@delegate_hash, delegate_hash.transform_values(&:dup))
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def initialize_dup(_)
|
54
|
-
@delegate_hash = Hash[delegate_hash]
|
55
|
-
super
|
56
|
-
end
|
57
|
-
|
58
|
-
def select
|
59
|
-
keys = types.keys | values.keys | delegate_hash.keys
|
60
|
-
keys.each_with_object({}) do |key, hash|
|
61
|
-
attribute = self[key]
|
62
|
-
if yield(key, attribute)
|
63
|
-
hash[key] = attribute
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def ==(other)
|
69
|
-
if other.is_a?(LazyAttributeHash)
|
70
|
-
materialize == other.materialize
|
71
|
-
else
|
72
|
-
materialize == other
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def marshal_dump
|
77
|
-
[@types, @values, @additional_types, @default_attributes, @delegate_hash]
|
78
|
-
end
|
79
|
-
|
80
|
-
def marshal_load(values)
|
81
|
-
if values.is_a?(Hash)
|
82
|
-
empty_hash = {}.freeze
|
83
|
-
initialize(empty_hash, empty_hash, empty_hash, empty_hash, values)
|
84
|
-
@materialized = true
|
85
|
-
else
|
86
|
-
initialize(*values)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
# TODO Change this to private once we've dropped Ruby 2.2 support.
|
91
|
-
# Workaround for Ruby 2.2 "private attribute?" warning.
|
92
|
-
protected
|
93
|
-
|
94
|
-
attr_reader :types, :values, :additional_types, :delegate_hash, :default_attributes
|
95
|
-
|
96
|
-
def materialize
|
97
|
-
unless @materialized
|
98
|
-
values.each_key { |key| self[key] }
|
99
|
-
types.each_key { |key| self[key] }
|
100
|
-
unless frozen?
|
101
|
-
@materialized = true
|
102
|
-
end
|
103
|
-
end
|
104
|
-
delegate_hash
|
105
|
-
end
|
106
|
-
|
107
|
-
private
|
108
|
-
|
109
|
-
def assign_default_value(name)
|
110
|
-
type = additional_types.fetch(name, types[name])
|
111
|
-
value_present = true
|
112
|
-
value = values.fetch(name) { value_present = false }
|
113
|
-
|
114
|
-
if value_present
|
115
|
-
delegate_hash[name] = Attribute.from_database(name, value, type)
|
116
|
-
elsif types.key?(name)
|
117
|
-
attr = default_attributes[name]
|
118
|
-
if attr
|
119
|
-
delegate_hash[name] = attr.dup
|
120
|
-
else
|
121
|
-
delegate_hash[name] = Attribute.uninitialized(name, type)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
class AttributeSet
|
3
|
-
# Attempts to do more intelligent YAML dumping of an
|
4
|
-
# ActiveRecord::AttributeSet to reduce the size of the resulting string
|
5
|
-
class YAMLEncoder # :nodoc:
|
6
|
-
def initialize(default_types)
|
7
|
-
@default_types = default_types
|
8
|
-
end
|
9
|
-
|
10
|
-
def encode(attribute_set, coder)
|
11
|
-
coder["concise_attributes"] = attribute_set.each_value.map do |attr|
|
12
|
-
if attr.type.equal?(default_types[attr.name])
|
13
|
-
attr.with_type(nil)
|
14
|
-
else
|
15
|
-
attr
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def decode(coder)
|
21
|
-
if coder["attributes"]
|
22
|
-
coder["attributes"]
|
23
|
-
else
|
24
|
-
attributes_hash = Hash[coder["concise_attributes"].map do |attr|
|
25
|
-
if attr.type.nil?
|
26
|
-
attr = attr.with_type(default_types[attr.name])
|
27
|
-
end
|
28
|
-
[attr.name, attr]
|
29
|
-
end]
|
30
|
-
AttributeSet.new(attributes_hash)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
# TODO Change this to private once we've dropped Ruby 2.2 support.
|
35
|
-
# Workaround for Ruby 2.2 "private attribute?" warning.
|
36
|
-
protected
|
37
|
-
|
38
|
-
attr_reader :default_types
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,113 +0,0 @@
|
|
1
|
-
require "active_record/attribute_set/builder"
|
2
|
-
require "active_record/attribute_set/yaml_encoder"
|
3
|
-
|
4
|
-
module ActiveRecord
|
5
|
-
class AttributeSet # :nodoc:
|
6
|
-
delegate :each_value, :fetch, :except, to: :attributes
|
7
|
-
|
8
|
-
def initialize(attributes)
|
9
|
-
@attributes = attributes
|
10
|
-
end
|
11
|
-
|
12
|
-
def [](name)
|
13
|
-
attributes[name] || Attribute.null(name)
|
14
|
-
end
|
15
|
-
|
16
|
-
def []=(name, value)
|
17
|
-
attributes[name] = value
|
18
|
-
end
|
19
|
-
|
20
|
-
def values_before_type_cast
|
21
|
-
attributes.transform_values(&:value_before_type_cast)
|
22
|
-
end
|
23
|
-
|
24
|
-
def to_hash
|
25
|
-
initialized_attributes.transform_values(&:value)
|
26
|
-
end
|
27
|
-
alias_method :to_h, :to_hash
|
28
|
-
|
29
|
-
def key?(name)
|
30
|
-
attributes.key?(name) && self[name].initialized?
|
31
|
-
end
|
32
|
-
|
33
|
-
def keys
|
34
|
-
attributes.each_key.select { |name| self[name].initialized? }
|
35
|
-
end
|
36
|
-
|
37
|
-
if defined?(JRUBY_VERSION)
|
38
|
-
# This form is significantly faster on JRuby, and this is one of our biggest hotspots.
|
39
|
-
# https://github.com/jruby/jruby/pull/2562
|
40
|
-
def fetch_value(name, &block)
|
41
|
-
self[name].value(&block)
|
42
|
-
end
|
43
|
-
else
|
44
|
-
def fetch_value(name)
|
45
|
-
self[name].value { |n| yield n if block_given? }
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def write_from_database(name, value)
|
50
|
-
attributes[name] = self[name].with_value_from_database(value)
|
51
|
-
end
|
52
|
-
|
53
|
-
def write_from_user(name, value)
|
54
|
-
attributes[name] = self[name].with_value_from_user(value)
|
55
|
-
end
|
56
|
-
|
57
|
-
def write_cast_value(name, value)
|
58
|
-
attributes[name] = self[name].with_cast_value(value)
|
59
|
-
end
|
60
|
-
|
61
|
-
def freeze
|
62
|
-
@attributes.freeze
|
63
|
-
super
|
64
|
-
end
|
65
|
-
|
66
|
-
def deep_dup
|
67
|
-
dup.tap do |copy|
|
68
|
-
copy.instance_variable_set(:@attributes, attributes.deep_dup)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def initialize_dup(_)
|
73
|
-
@attributes = attributes.dup
|
74
|
-
super
|
75
|
-
end
|
76
|
-
|
77
|
-
def initialize_clone(_)
|
78
|
-
@attributes = attributes.clone
|
79
|
-
super
|
80
|
-
end
|
81
|
-
|
82
|
-
def reset(key)
|
83
|
-
if key?(key)
|
84
|
-
write_from_database(key, nil)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
def accessed
|
89
|
-
attributes.select { |_, attr| attr.has_been_read? }.keys
|
90
|
-
end
|
91
|
-
|
92
|
-
def map(&block)
|
93
|
-
new_attributes = attributes.transform_values(&block)
|
94
|
-
AttributeSet.new(new_attributes)
|
95
|
-
end
|
96
|
-
|
97
|
-
def ==(other)
|
98
|
-
attributes == other.attributes
|
99
|
-
end
|
100
|
-
|
101
|
-
# TODO Change this to private once we've dropped Ruby 2.2 support.
|
102
|
-
# Workaround for Ruby 2.2 "private attribute?" warning.
|
103
|
-
protected
|
104
|
-
|
105
|
-
attr_reader :attributes
|
106
|
-
|
107
|
-
private
|
108
|
-
|
109
|
-
def initialized_attributes
|
110
|
-
attributes.select { |_, attr| attr.initialized? }
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|