activerecord 4.2.0 → 5.2.8.1
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 +5 -5
- data/CHANGELOG.md +640 -928
- data/MIT-LICENSE +2 -2
- data/README.rdoc +10 -11
- data/examples/performance.rb +32 -31
- data/examples/simple.rb +5 -4
- data/lib/active_record/aggregations.rb +264 -247
- data/lib/active_record/association_relation.rb +24 -6
- data/lib/active_record/associations/alias_tracker.rb +29 -35
- data/lib/active_record/associations/association.rb +87 -41
- data/lib/active_record/associations/association_scope.rb +106 -132
- data/lib/active_record/associations/belongs_to_association.rb +55 -36
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
- data/lib/active_record/associations/builder/association.rb +29 -38
- data/lib/active_record/associations/builder/belongs_to.rb +77 -30
- data/lib/active_record/associations/builder/collection_association.rb +14 -23
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +50 -39
- data/lib/active_record/associations/builder/has_many.rb +6 -4
- data/lib/active_record/associations/builder/has_one.rb +13 -6
- data/lib/active_record/associations/builder/singular_association.rb +15 -11
- data/lib/active_record/associations/collection_association.rb +145 -266
- data/lib/active_record/associations/collection_proxy.rb +242 -138
- data/lib/active_record/associations/foreign_association.rb +13 -0
- data/lib/active_record/associations/has_many_association.rb +35 -75
- data/lib/active_record/associations/has_many_through_association.rb +51 -69
- data/lib/active_record/associations/has_one_association.rb +39 -24
- data/lib/active_record/associations/has_one_through_association.rb +18 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +40 -81
- data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
- data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
- data/lib/active_record/associations/join_dependency.rb +134 -154
- data/lib/active_record/associations/preloader/association.rb +85 -116
- data/lib/active_record/associations/preloader/through_association.rb +85 -74
- data/lib/active_record/associations/preloader.rb +83 -93
- data/lib/active_record/associations/singular_association.rb +27 -40
- data/lib/active_record/associations/through_association.rb +48 -23
- data/lib/active_record/associations.rb +1732 -1596
- data/lib/active_record/attribute_assignment.rb +58 -182
- data/lib/active_record/attribute_decorators.rb +39 -15
- data/lib/active_record/attribute_methods/before_type_cast.rb +12 -5
- data/lib/active_record/attribute_methods/dirty.rb +94 -125
- data/lib/active_record/attribute_methods/primary_key.rb +86 -71
- data/lib/active_record/attribute_methods/query.rb +4 -2
- data/lib/active_record/attribute_methods/read.rb +45 -63
- data/lib/active_record/attribute_methods/serialization.rb +40 -20
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +62 -36
- data/lib/active_record/attribute_methods/write.rb +31 -46
- data/lib/active_record/attribute_methods.rb +170 -117
- data/lib/active_record/attributes.rb +201 -74
- data/lib/active_record/autosave_association.rb +118 -45
- data/lib/active_record/base.rb +60 -48
- data/lib/active_record/callbacks.rb +97 -57
- data/lib/active_record/coders/json.rb +3 -1
- data/lib/active_record/coders/yaml_column.rb +37 -13
- data/lib/active_record/collection_cache_key.rb +53 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +712 -284
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +10 -5
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +254 -87
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +72 -22
- data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -52
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +6 -4
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +67 -46
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +328 -217
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +81 -36
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +617 -212
- data/lib/active_record/connection_adapters/abstract/transaction.rb +139 -75
- data/lib/active_record/connection_adapters/abstract_adapter.rb +332 -191
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +567 -563
- data/lib/active_record/connection_adapters/column.rb +50 -41
- data/lib/active_record/connection_adapters/connection_specification.rb +147 -135
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +33 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +140 -0
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -0
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +73 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +87 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +80 -0
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +148 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +35 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +42 -195
- data/lib/active_record/connection_adapters/postgresql/column.rb +35 -11
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +46 -115
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -57
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +10 -6
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +5 -2
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -13
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +7 -3
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
- data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +65 -51
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +107 -47
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +65 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +144 -90
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +466 -280
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +39 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +439 -330
- data/lib/active_record/connection_adapters/schema_cache.rb +48 -24
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +34 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +67 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +106 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +269 -324
- data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
- data/lib/active_record/connection_handling.rb +40 -27
- data/lib/active_record/core.rb +205 -202
- data/lib/active_record/counter_cache.rb +80 -37
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +87 -105
- data/lib/active_record/enum.rb +136 -90
- data/lib/active_record/errors.rb +180 -52
- data/lib/active_record/explain.rb +23 -11
- data/lib/active_record/explain_registry.rb +4 -2
- data/lib/active_record/explain_subscriber.rb +11 -6
- data/lib/active_record/fixture_set/file.rb +35 -9
- data/lib/active_record/fixtures.rb +193 -135
- data/lib/active_record/gem_version.rb +5 -3
- data/lib/active_record/inheritance.rb +148 -112
- data/lib/active_record/integration.rb +70 -28
- data/lib/active_record/internal_metadata.rb +45 -0
- data/lib/active_record/legacy_yaml_adapter.rb +48 -0
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +92 -98
- data/lib/active_record/locking/pessimistic.rb +15 -3
- data/lib/active_record/log_subscriber.rb +95 -33
- data/lib/active_record/migration/command_recorder.rb +133 -90
- data/lib/active_record/migration/compatibility.rb +217 -0
- data/lib/active_record/migration/join_table.rb +8 -6
- data/lib/active_record/migration.rb +594 -267
- data/lib/active_record/model_schema.rb +292 -111
- data/lib/active_record/nested_attributes.rb +266 -214
- data/lib/active_record/no_touching.rb +8 -2
- data/lib/active_record/null_relation.rb +24 -37
- data/lib/active_record/persistence.rb +350 -119
- data/lib/active_record/query_cache.rb +13 -24
- data/lib/active_record/querying.rb +19 -17
- data/lib/active_record/railtie.rb +117 -35
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +9 -3
- data/lib/active_record/railties/databases.rake +160 -174
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +447 -288
- data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
- data/lib/active_record/relation/batches.rb +204 -55
- data/lib/active_record/relation/calculations.rb +259 -244
- data/lib/active_record/relation/delegation.rb +67 -60
- data/lib/active_record/relation/finder_methods.rb +290 -253
- data/lib/active_record/relation/from_clause.rb +26 -0
- data/lib/active_record/relation/merger.rb +91 -68
- data/lib/active_record/relation/predicate_builder/array_handler.rb +24 -23
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +19 -0
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +20 -0
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +42 -0
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
- data/lib/active_record/relation/predicate_builder.rb +118 -92
- data/lib/active_record/relation/query_attribute.rb +45 -0
- data/lib/active_record/relation/query_methods.rb +446 -389
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +18 -16
- data/lib/active_record/relation/where_clause.rb +186 -0
- data/lib/active_record/relation/where_clause_factory.rb +34 -0
- data/lib/active_record/relation.rb +287 -339
- data/lib/active_record/result.rb +54 -36
- data/lib/active_record/runtime_registry.rb +6 -4
- data/lib/active_record/sanitization.rb +155 -124
- data/lib/active_record/schema.rb +30 -24
- data/lib/active_record/schema_dumper.rb +91 -87
- data/lib/active_record/schema_migration.rb +19 -19
- data/lib/active_record/scoping/default.rb +102 -84
- data/lib/active_record/scoping/named.rb +81 -32
- data/lib/active_record/scoping.rb +45 -26
- data/lib/active_record/secure_token.rb +40 -0
- data/lib/active_record/serialization.rb +5 -5
- data/lib/active_record/statement_cache.rb +45 -35
- data/lib/active_record/store.rb +42 -36
- data/lib/active_record/suppressor.rb +61 -0
- data/lib/active_record/table_metadata.rb +82 -0
- data/lib/active_record/tasks/database_tasks.rb +136 -95
- data/lib/active_record/tasks/mysql_database_tasks.rb +59 -89
- data/lib/active_record/tasks/postgresql_database_tasks.rb +84 -31
- data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -16
- data/lib/active_record/timestamp.rb +70 -38
- data/lib/active_record/touch_later.rb +64 -0
- data/lib/active_record/transactions.rb +208 -123
- data/lib/active_record/translation.rb +2 -0
- data/lib/active_record/type/adapter_specific_registry.rb +136 -0
- data/lib/active_record/type/date.rb +4 -41
- data/lib/active_record/type/date_time.rb +4 -38
- data/lib/active_record/type/decimal_without_scale.rb +6 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +13 -5
- data/lib/active_record/type/internal/timezone.rb +17 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +30 -15
- data/lib/active_record/type/text.rb +2 -2
- data/lib/active_record/type/time.rb +11 -16
- data/lib/active_record/type/type_map.rb +15 -17
- data/lib/active_record/type/unsigned_integer.rb +9 -7
- data/lib/active_record/type.rb +79 -23
- data/lib/active_record/type_caster/connection.rb +33 -0
- data/lib/active_record/type_caster/map.rb +23 -0
- data/lib/active_record/type_caster.rb +9 -0
- data/lib/active_record/validations/absence.rb +25 -0
- data/lib/active_record/validations/associated.rb +13 -4
- data/lib/active_record/validations/length.rb +26 -0
- data/lib/active_record/validations/presence.rb +14 -13
- data/lib/active_record/validations/uniqueness.rb +41 -32
- data/lib/active_record/validations.rb +38 -35
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +36 -21
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +43 -35
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +8 -6
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +8 -7
- data/lib/rails/generators/active_record/migration.rb +18 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +18 -22
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +3 -0
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +77 -53
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
- data/lib/active_record/associations/preloader/collection_association.rb +0 -24
- data/lib/active_record/associations/preloader/has_many.rb +0 -17
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -23
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -21
- data/lib/active_record/attribute.rb +0 -149
- data/lib/active_record/attribute_set/builder.rb +0 -86
- data/lib/active_record/attribute_set.rb +0 -77
- 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/float.rb +0 -21
- data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
- data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- 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/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/time_value.rb +0 -38
- data/lib/active_record/type/value.rb +0 -101
- /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
data/lib/active_record/core.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/hash/indifferent_access"
|
4
|
+
require "active_support/core_ext/string/filters"
|
5
|
+
require "concurrent/map"
|
5
6
|
|
6
7
|
module ActiveRecord
|
7
8
|
module Core
|
@@ -16,6 +17,13 @@ module ActiveRecord
|
|
16
17
|
# retrieved on both a class and instance level by calling +logger+.
|
17
18
|
mattr_accessor :logger, instance_writer: false
|
18
19
|
|
20
|
+
##
|
21
|
+
# :singleton-method:
|
22
|
+
#
|
23
|
+
# Specifies if the methods calling database queries should be logged below
|
24
|
+
# their relevant queries. Defaults to false.
|
25
|
+
mattr_accessor :verbose_query_logs, instance_writer: false, default: false
|
26
|
+
|
19
27
|
##
|
20
28
|
# Contains the database configuration - as is typically stored in config/database.yml -
|
21
29
|
# as a Hash.
|
@@ -56,8 +64,7 @@ module ActiveRecord
|
|
56
64
|
# :singleton-method:
|
57
65
|
# Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
|
58
66
|
# dates and times from the database. This is set to :utc by default.
|
59
|
-
mattr_accessor :default_timezone, instance_writer: false
|
60
|
-
self.default_timezone = :utc
|
67
|
+
mattr_accessor :default_timezone, instance_writer: false, default: :utc
|
61
68
|
|
62
69
|
##
|
63
70
|
# :singleton-method:
|
@@ -67,14 +74,27 @@ module ActiveRecord
|
|
67
74
|
# ActiveRecord::Schema file which can be loaded into any database that
|
68
75
|
# supports migrations. Use :ruby if you want to have different database
|
69
76
|
# adapters for, e.g., your development and test environments.
|
70
|
-
mattr_accessor :schema_format, instance_writer: false
|
71
|
-
|
77
|
+
mattr_accessor :schema_format, instance_writer: false, default: :ruby
|
78
|
+
|
79
|
+
##
|
80
|
+
# :singleton-method:
|
81
|
+
# Specifies if an error should be raised if the query has an order being
|
82
|
+
# ignored when doing batch queries. Useful in applications where the
|
83
|
+
# scope being ignored is error-worthy, rather than a warning.
|
84
|
+
mattr_accessor :error_on_ignored_order, instance_writer: false, default: false
|
85
|
+
|
86
|
+
# :singleton-method:
|
87
|
+
# Specify the behavior for unsafe raw query methods. Values are as follows
|
88
|
+
# deprecated - Warnings are logged when unsafe raw SQL is passed to
|
89
|
+
# query methods.
|
90
|
+
# disabled - Unsafe raw SQL passed to query methods results in
|
91
|
+
# UnknownAttributeReference exception.
|
92
|
+
mattr_accessor :allow_unsafe_raw_sql, instance_writer: false, default: :deprecated
|
72
93
|
|
73
94
|
##
|
74
95
|
# :singleton-method:
|
75
96
|
# Specify whether or not to use timestamps for migration versions
|
76
|
-
mattr_accessor :timestamped_migrations, instance_writer: false
|
77
|
-
self.timestamped_migrations = true
|
97
|
+
mattr_accessor :timestamped_migrations, instance_writer: false, default: true
|
78
98
|
|
79
99
|
##
|
80
100
|
# :singleton-method:
|
@@ -82,20 +102,40 @@ module ActiveRecord
|
|
82
102
|
# db:migrate rake task. This is true by default, which is useful for the
|
83
103
|
# development environment. This should ideally be false in the production
|
84
104
|
# environment where dumping schema is rarely needed.
|
85
|
-
mattr_accessor :dump_schema_after_migration, instance_writer: false
|
86
|
-
|
105
|
+
mattr_accessor :dump_schema_after_migration, instance_writer: false, default: true
|
106
|
+
|
107
|
+
##
|
108
|
+
# :singleton-method:
|
109
|
+
# Specifies which database schemas to dump when calling db:structure:dump.
|
110
|
+
# If the value is :schema_search_path (the default), any schemas listed in
|
111
|
+
# schema_search_path are dumped. Use :all to dump all schemas regardless
|
112
|
+
# of schema_search_path, or a string of comma separated schemas for a
|
113
|
+
# custom list.
|
114
|
+
mattr_accessor :dump_schemas, instance_writer: false, default: :schema_search_path
|
115
|
+
|
116
|
+
##
|
117
|
+
# :singleton-method:
|
118
|
+
# Specify a threshold for the size of query result sets. If the number of
|
119
|
+
# records in the set exceeds the threshold, a warning is logged. This can
|
120
|
+
# be used to identify queries which load thousands of records and
|
121
|
+
# potentially cause memory bloat.
|
122
|
+
mattr_accessor :warn_on_records_fetched_greater_than, instance_writer: false
|
87
123
|
|
88
124
|
mattr_accessor :maintain_test_schema, instance_accessor: false
|
89
125
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
126
|
+
mattr_accessor :belongs_to_required_by_default, instance_accessor: false
|
127
|
+
|
128
|
+
##
|
129
|
+
# :singleton-method:
|
130
|
+
# Application configurable boolean that instructs the YAML Coder to use
|
131
|
+
# an unsafe load if set to true.
|
132
|
+
mattr_accessor :use_yaml_unsafe_load, instance_writer: false, default: false
|
133
|
+
|
134
|
+
# Application configurable array that provides additional permitted classes
|
135
|
+
# to Psych safe_load in the YAML Coder
|
136
|
+
mattr_accessor :yaml_column_permitted_classes, instance_writer: false, default: []
|
96
137
|
|
97
138
|
class_attribute :default_connection_handler, instance_writer: false
|
98
|
-
class_attribute :find_by_statement_cache
|
99
139
|
|
100
140
|
def self.connection_handler
|
101
141
|
ActiveRecord::RuntimeRegistry.connection_handler || default_connection_handler
|
@@ -108,101 +148,95 @@ module ActiveRecord
|
|
108
148
|
self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
|
109
149
|
end
|
110
150
|
|
111
|
-
module ClassMethods
|
151
|
+
module ClassMethods # :nodoc:
|
112
152
|
def allocate
|
113
153
|
define_attribute_methods
|
114
154
|
super
|
115
155
|
end
|
116
156
|
|
117
|
-
def initialize_find_by_cache
|
118
|
-
|
157
|
+
def initialize_find_by_cache # :nodoc:
|
158
|
+
@find_by_statement_cache = { true => Concurrent::Map.new, false => Concurrent::Map.new }
|
119
159
|
end
|
120
160
|
|
121
|
-
def inherited(child_class)
|
161
|
+
def inherited(child_class) # :nodoc:
|
162
|
+
# initialize cache at class definition for thread safety
|
122
163
|
child_class.initialize_find_by_cache
|
123
164
|
super
|
124
165
|
end
|
125
166
|
|
126
|
-
def find(*ids)
|
167
|
+
def find(*ids) # :nodoc:
|
127
168
|
# We don't have cache keys for this stuff yet
|
128
169
|
return super unless ids.length == 1
|
129
|
-
# Allow symbols to super to maintain compatibility for deprecated finders until Rails 5
|
130
|
-
return super if ids.first.kind_of?(Symbol)
|
131
170
|
return super if block_given? ||
|
132
171
|
primary_key.nil? ||
|
133
|
-
|
134
|
-
columns_hash.include?(inheritance_column)
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
141
|
-
You are passing an instance of ActiveRecord::Base to `find`.
|
142
|
-
Please pass the id of the object by calling `.id`
|
143
|
-
MSG
|
144
|
-
end
|
172
|
+
scope_attributes? ||
|
173
|
+
columns_hash.include?(inheritance_column)
|
174
|
+
|
175
|
+
id = ids.first
|
176
|
+
|
177
|
+
return super if StatementCache.unsupported_value?(id)
|
178
|
+
|
145
179
|
key = primary_key
|
146
180
|
|
147
|
-
|
148
|
-
|
149
|
-
where(key => params.bind).limit(1)
|
150
|
-
}
|
181
|
+
statement = cached_find_by_statement(key) { |params|
|
182
|
+
where(key => params.bind).limit(1)
|
151
183
|
}
|
152
|
-
|
184
|
+
|
185
|
+
record = statement.execute([id], connection).first
|
153
186
|
unless record
|
154
|
-
raise RecordNotFound
|
187
|
+
raise RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}",
|
188
|
+
name, primary_key, id)
|
155
189
|
end
|
156
190
|
record
|
157
|
-
rescue RangeError
|
158
|
-
raise RecordNotFound
|
191
|
+
rescue ::RangeError
|
192
|
+
raise RecordNotFound.new("Couldn't find #{name} with an out of range value for '#{primary_key}'",
|
193
|
+
name, primary_key)
|
159
194
|
end
|
160
195
|
|
161
|
-
def find_by(*args)
|
162
|
-
return super if
|
163
|
-
|
196
|
+
def find_by(*args) # :nodoc:
|
197
|
+
return super if scope_attributes? || reflect_on_all_aggregations.any? ||
|
198
|
+
columns_hash.key?(inheritance_column) && base_class != self
|
164
199
|
|
165
200
|
hash = args.first
|
166
201
|
|
167
|
-
return super if hash.values.any? { |v|
|
168
|
-
|
202
|
+
return super if !(Hash === hash) || hash.values.any? { |v|
|
203
|
+
StatementCache.unsupported_value?(v)
|
169
204
|
}
|
170
205
|
|
171
206
|
# We can't cache Post.find_by(author: david) ...yet
|
172
207
|
return super unless hash.keys.all? { |k| columns_hash.has_key?(k.to_s) }
|
173
208
|
|
174
|
-
|
209
|
+
keys = hash.keys
|
175
210
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
wheres = key.each_with_object({}) { |param,o|
|
180
|
-
o[param] = params.bind
|
181
|
-
}
|
182
|
-
klass.where(wheres).limit(1)
|
211
|
+
statement = cached_find_by_statement(keys) { |params|
|
212
|
+
wheres = keys.each_with_object({}) { |param, o|
|
213
|
+
o[param] = params.bind
|
183
214
|
}
|
215
|
+
where(wheres).limit(1)
|
184
216
|
}
|
185
217
|
begin
|
186
|
-
|
187
|
-
rescue TypeError
|
188
|
-
raise ActiveRecord::StatementInvalid
|
189
|
-
rescue RangeError
|
218
|
+
statement.execute(hash.values, connection).first
|
219
|
+
rescue TypeError
|
220
|
+
raise ActiveRecord::StatementInvalid
|
221
|
+
rescue ::RangeError
|
190
222
|
nil
|
191
223
|
end
|
192
224
|
end
|
193
225
|
|
194
|
-
def find_by!(*args)
|
195
|
-
find_by(*args)
|
226
|
+
def find_by!(*args) # :nodoc:
|
227
|
+
find_by(*args) || raise(RecordNotFound.new("Couldn't find #{name}", name))
|
196
228
|
end
|
197
229
|
|
198
|
-
def initialize_generated_modules
|
230
|
+
def initialize_generated_modules # :nodoc:
|
199
231
|
generated_association_methods
|
200
232
|
end
|
201
233
|
|
202
234
|
def generated_association_methods
|
203
235
|
@generated_association_methods ||= begin
|
204
236
|
mod = const_set(:GeneratedAssociationMethods, Module.new)
|
237
|
+
private_constant :GeneratedAssociationMethods
|
205
238
|
include mod
|
239
|
+
|
206
240
|
mod
|
207
241
|
end
|
208
242
|
end
|
@@ -216,14 +250,14 @@ module ActiveRecord
|
|
216
250
|
elsif !connected?
|
217
251
|
"#{super} (call '#{super}.connection' to establish a connection)"
|
218
252
|
elsif table_exists?
|
219
|
-
attr_list =
|
253
|
+
attr_list = attribute_types.map { |name, type| "#{name}: #{type.type}" } * ", "
|
220
254
|
"#{super}(#{attr_list})"
|
221
255
|
else
|
222
256
|
"#{super}(Table doesn't exist)"
|
223
257
|
end
|
224
258
|
end
|
225
259
|
|
226
|
-
# Overwrite the default class equality method to provide support for
|
260
|
+
# Overwrite the default class equality method to provide support for decorated models.
|
227
261
|
def ===(object)
|
228
262
|
object.is_a?(self)
|
229
263
|
end
|
@@ -231,33 +265,46 @@ module ActiveRecord
|
|
231
265
|
# Returns an instance of <tt>Arel::Table</tt> loaded with the current table name.
|
232
266
|
#
|
233
267
|
# class Post < ActiveRecord::Base
|
234
|
-
# scope :published_and_commented, -> { published.and(
|
268
|
+
# scope :published_and_commented, -> { published.and(arel_table[:comments_count].gt(0)) }
|
235
269
|
# end
|
236
270
|
def arel_table # :nodoc:
|
237
|
-
@arel_table ||= Arel::Table.new(table_name,
|
271
|
+
@arel_table ||= Arel::Table.new(table_name, type_caster: type_caster)
|
238
272
|
end
|
239
273
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
274
|
+
def arel_attribute(name, table = arel_table) # :nodoc:
|
275
|
+
name = attribute_alias(name) if attribute_alias?(name)
|
276
|
+
table[name]
|
277
|
+
end
|
278
|
+
|
279
|
+
def predicate_builder # :nodoc:
|
280
|
+
@predicate_builder ||= PredicateBuilder.new(table_metadata)
|
281
|
+
end
|
282
|
+
|
283
|
+
def type_caster # :nodoc:
|
284
|
+
TypeCaster::Map.new(self)
|
248
285
|
end
|
249
286
|
|
250
287
|
private
|
251
288
|
|
252
|
-
|
253
|
-
|
289
|
+
def cached_find_by_statement(key, &block)
|
290
|
+
cache = @find_by_statement_cache[connection.prepared_statements]
|
291
|
+
cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
|
292
|
+
end
|
254
293
|
|
255
|
-
|
256
|
-
relation.
|
257
|
-
|
258
|
-
|
294
|
+
def relation
|
295
|
+
relation = Relation.create(self)
|
296
|
+
|
297
|
+
if finder_needs_type_condition? && !ignore_default_scope?
|
298
|
+
relation.where!(type_condition)
|
299
|
+
relation.create_with!(inheritance_column.to_s => sti_name)
|
300
|
+
else
|
301
|
+
relation
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
def table_metadata
|
306
|
+
TableMetadata.new(self, arel_table)
|
259
307
|
end
|
260
|
-
end
|
261
308
|
end
|
262
309
|
|
263
310
|
# New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
|
@@ -268,40 +315,45 @@ module ActiveRecord
|
|
268
315
|
# ==== Example:
|
269
316
|
# # Instantiates a single new object
|
270
317
|
# User.new(first_name: 'Jamie')
|
271
|
-
def initialize(attributes = nil
|
272
|
-
|
318
|
+
def initialize(attributes = nil)
|
319
|
+
self.class.define_attribute_methods
|
320
|
+
@attributes = self.class._default_attributes.deep_dup
|
273
321
|
|
274
322
|
init_internals
|
275
323
|
initialize_internals_callback
|
276
324
|
|
277
|
-
|
278
|
-
# +options+ argument is only needed to make protected_attributes gem easier to hook.
|
279
|
-
# Remove it when we drop support to this gem.
|
280
|
-
init_attributes(attributes, options) if attributes
|
325
|
+
assign_attributes(attributes) if attributes
|
281
326
|
|
282
327
|
yield self if block_given?
|
283
328
|
_run_initialize_callbacks
|
284
329
|
end
|
285
330
|
|
286
|
-
# Initialize an empty model object from +coder+. +coder+
|
287
|
-
# the
|
288
|
-
#
|
331
|
+
# Initialize an empty model object from +coder+. +coder+ should be
|
332
|
+
# the result of previously encoding an Active Record model, using
|
333
|
+
# #encode_with.
|
289
334
|
#
|
290
335
|
# class Post < ActiveRecord::Base
|
291
336
|
# end
|
292
337
|
#
|
338
|
+
# old_post = Post.new(title: "hello world")
|
339
|
+
# coder = {}
|
340
|
+
# old_post.encode_with(coder)
|
341
|
+
#
|
293
342
|
# post = Post.allocate
|
294
|
-
# post.init_with(
|
343
|
+
# post.init_with(coder)
|
295
344
|
# post.title # => 'hello world'
|
296
345
|
def init_with(coder)
|
297
|
-
|
346
|
+
coder = LegacyYamlAdapter.convert(self.class, coder)
|
347
|
+
@attributes = self.class.yaml_encoder.decode(coder)
|
298
348
|
|
299
349
|
init_internals
|
300
350
|
|
301
|
-
@new_record = coder[
|
351
|
+
@new_record = coder["new_record"]
|
302
352
|
|
303
353
|
self.class.define_attribute_methods
|
304
354
|
|
355
|
+
yield self if block_given?
|
356
|
+
|
305
357
|
_run_find_callbacks
|
306
358
|
_run_initialize_callbacks
|
307
359
|
|
@@ -336,23 +388,22 @@ module ActiveRecord
|
|
336
388
|
|
337
389
|
##
|
338
390
|
def initialize_dup(other) # :nodoc:
|
339
|
-
@attributes = @attributes.
|
391
|
+
@attributes = @attributes.deep_dup
|
340
392
|
@attributes.reset(self.class.primary_key)
|
341
393
|
|
342
394
|
_run_initialize_callbacks
|
343
395
|
|
344
|
-
@
|
345
|
-
@
|
346
|
-
|
347
|
-
@
|
348
|
-
@destroyed = false
|
396
|
+
@new_record = true
|
397
|
+
@destroyed = false
|
398
|
+
@_start_transaction_state = {}
|
399
|
+
@transaction_state = nil
|
349
400
|
|
350
401
|
super
|
351
402
|
end
|
352
403
|
|
353
404
|
# Populate +coder+ with attributes about this record that should be
|
354
405
|
# serialized. The structure of +coder+ defined in this method is
|
355
|
-
# guaranteed to match the structure of +coder+ passed to the
|
406
|
+
# guaranteed to match the structure of +coder+ passed to the #init_with
|
356
407
|
# method.
|
357
408
|
#
|
358
409
|
# Example:
|
@@ -363,10 +414,9 @@ module ActiveRecord
|
|
363
414
|
# Post.new.encode_with(coder)
|
364
415
|
# coder # => {"attributes" => {"id" => nil, ... }}
|
365
416
|
def encode_with(coder)
|
366
|
-
|
367
|
-
coder[
|
368
|
-
coder[
|
369
|
-
coder['new_record'] = new_record?
|
417
|
+
self.class.yaml_encoder.encode(@attributes, coder)
|
418
|
+
coder["new_record"] = new_record?
|
419
|
+
coder["active_record_yaml_version"] = 2
|
370
420
|
end
|
371
421
|
|
372
422
|
# Returns true if +comparison_object+ is the same exact object, or +comparison_object+
|
@@ -390,7 +440,7 @@ module ActiveRecord
|
|
390
440
|
# [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
|
391
441
|
def hash
|
392
442
|
if id
|
393
|
-
id.hash
|
443
|
+
self.class.hash ^ id.hash
|
394
444
|
else
|
395
445
|
super
|
396
446
|
end
|
@@ -412,7 +462,7 @@ module ActiveRecord
|
|
412
462
|
# Allows sort on objects
|
413
463
|
def <=>(other_object)
|
414
464
|
if other_object.is_a?(self.class)
|
415
|
-
|
465
|
+
to_key <=> other_object.to_key
|
416
466
|
else
|
417
467
|
super
|
418
468
|
end
|
@@ -438,129 +488,82 @@ module ActiveRecord
|
|
438
488
|
# We check defined?(@attributes) not to issue warnings if the object is
|
439
489
|
# allocated but not initialized.
|
440
490
|
inspection = if defined?(@attributes) && @attributes
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
491
|
+
self.class.attribute_names.collect do |name|
|
492
|
+
if has_attribute?(name)
|
493
|
+
"#{name}: #{attribute_for_inspect(name)}"
|
494
|
+
end
|
495
|
+
end.compact.join(", ")
|
496
|
+
else
|
497
|
+
"not initialized"
|
498
|
+
end
|
499
|
+
|
449
500
|
"#<#{self.class} #{inspection}>"
|
450
501
|
end
|
451
502
|
|
452
|
-
# Takes a PP and prettily prints this record to it, allowing you to get a nice result from
|
503
|
+
# Takes a PP and prettily prints this record to it, allowing you to get a nice result from <tt>pp record</tt>
|
453
504
|
# when pp is required.
|
454
505
|
def pretty_print(pp)
|
506
|
+
return super if custom_inspect_method_defined?
|
455
507
|
pp.object_address_group(self) do
|
456
508
|
if defined?(@attributes) && @attributes
|
457
509
|
column_names = self.class.column_names.select { |name| has_attribute?(name) || new_record? }
|
458
|
-
pp.seplist(column_names, proc { pp.text
|
510
|
+
pp.seplist(column_names, proc { pp.text "," }) do |column_name|
|
459
511
|
column_value = read_attribute(column_name)
|
460
|
-
pp.breakable
|
512
|
+
pp.breakable " "
|
461
513
|
pp.group(1) do
|
462
514
|
pp.text column_name
|
463
|
-
pp.text
|
515
|
+
pp.text ":"
|
464
516
|
pp.breakable
|
465
517
|
pp.pp column_value
|
466
518
|
end
|
467
519
|
end
|
468
520
|
else
|
469
|
-
pp.breakable
|
470
|
-
pp.text
|
521
|
+
pp.breakable " "
|
522
|
+
pp.text "not initialized"
|
471
523
|
end
|
472
524
|
end
|
473
525
|
end
|
474
526
|
|
475
527
|
# Returns a hash of the given methods with their names as keys and returned values as values.
|
476
528
|
def slice(*methods)
|
477
|
-
Hash[methods.map! { |method| [method, public_send(method)] }].with_indifferent_access
|
478
|
-
end
|
479
|
-
|
480
|
-
def set_transaction_state(state) # :nodoc:
|
481
|
-
@transaction_state = state
|
482
|
-
end
|
483
|
-
|
484
|
-
def has_transactional_callbacks? # :nodoc:
|
485
|
-
!_rollback_callbacks.empty? || !_commit_callbacks.empty? || !_create_callbacks.empty?
|
529
|
+
Hash[methods.flatten.map! { |method| [method, public_send(method)] }].with_indifferent_access
|
486
530
|
end
|
487
531
|
|
488
532
|
private
|
489
533
|
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
# This method checks to see if the ActiveRecord object's state reflects
|
501
|
-
# the TransactionState, and rolls back or commits the ActiveRecord object
|
502
|
-
# as appropriate.
|
503
|
-
#
|
504
|
-
# Since ActiveRecord objects can be inside multiple transactions, this
|
505
|
-
# method recursively goes through the parent of the TransactionState and
|
506
|
-
# checks if the ActiveRecord object reflects the state of the object.
|
507
|
-
def sync_with_transaction_state
|
508
|
-
update_attributes_from_transaction_state(@transaction_state, 0)
|
509
|
-
end
|
510
|
-
|
511
|
-
def update_attributes_from_transaction_state(transaction_state, depth)
|
512
|
-
if transaction_state && transaction_state.finalized? && !has_transactional_callbacks?
|
513
|
-
unless @reflects_state[depth]
|
514
|
-
restore_transaction_record_state if transaction_state.rolledback?
|
515
|
-
clear_transaction_record_state
|
516
|
-
@reflects_state[depth] = true
|
517
|
-
end
|
518
|
-
|
519
|
-
if transaction_state.parent && !@reflects_state[depth+1]
|
520
|
-
update_attributes_from_transaction_state(transaction_state.parent, depth+1)
|
521
|
-
end
|
534
|
+
# +Array#flatten+ will call +#to_ary+ (recursively) on each of the elements of
|
535
|
+
# the array, and then rescues from the possible +NoMethodError+. If those elements are
|
536
|
+
# +ActiveRecord::Base+'s, then this triggers the various +method_missing+'s that we have,
|
537
|
+
# which significantly impacts upon performance.
|
538
|
+
#
|
539
|
+
# So we can avoid the +method_missing+ hit by explicitly defining +#to_ary+ as +nil+ here.
|
540
|
+
#
|
541
|
+
# See also https://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary.html
|
542
|
+
def to_ary
|
543
|
+
nil
|
522
544
|
end
|
523
|
-
end
|
524
545
|
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
nil
|
535
|
-
end
|
536
|
-
|
537
|
-
def init_internals
|
538
|
-
@aggregation_cache = {}
|
539
|
-
@association_cache = {}
|
540
|
-
@readonly = false
|
541
|
-
@destroyed = false
|
542
|
-
@marked_for_destruction = false
|
543
|
-
@destroyed_by_association = nil
|
544
|
-
@new_record = true
|
545
|
-
@txn = nil
|
546
|
-
@_start_transaction_state = {}
|
547
|
-
@transaction_state = nil
|
548
|
-
@reflects_state = [false]
|
549
|
-
end
|
546
|
+
def init_internals
|
547
|
+
@readonly = false
|
548
|
+
@destroyed = false
|
549
|
+
@marked_for_destruction = false
|
550
|
+
@destroyed_by_association = nil
|
551
|
+
@new_record = true
|
552
|
+
@_start_transaction_state = {}
|
553
|
+
@transaction_state = nil
|
554
|
+
end
|
550
555
|
|
551
|
-
|
552
|
-
|
556
|
+
def initialize_internals_callback
|
557
|
+
end
|
553
558
|
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
+
def thaw
|
560
|
+
if frozen?
|
561
|
+
@attributes = @attributes.dup
|
562
|
+
end
|
563
|
+
end
|
559
564
|
|
560
|
-
|
561
|
-
|
562
|
-
@attributes = @attributes.dup
|
565
|
+
def custom_inspect_method_defined?
|
566
|
+
self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner
|
563
567
|
end
|
564
|
-
end
|
565
568
|
end
|
566
569
|
end
|