activerecord 4.2.11.1 → 5.2.4.5
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 +594 -1620
- 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 +263 -249
- data/lib/active_record/association_relation.rb +11 -6
- data/lib/active_record/associations/alias_tracker.rb +29 -35
- data/lib/active_record/associations/association.rb +77 -43
- data/lib/active_record/associations/association_scope.rb +106 -133
- data/lib/active_record/associations/belongs_to_association.rb +52 -41
- 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 +9 -22
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +42 -35
- 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 +139 -280
- data/lib/active_record/associations/collection_proxy.rb +231 -133
- data/lib/active_record/associations/foreign_association.rb +3 -1
- data/lib/active_record/associations/has_many_association.rb +34 -89
- data/lib/active_record/associations/has_many_through_association.rb +49 -76
- data/lib/active_record/associations/has_one_association.rb +38 -24
- data/lib/active_record/associations/has_one_through_association.rb +18 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +40 -87
- 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 +133 -159
- data/lib/active_record/associations/preloader/association.rb +85 -120
- data/lib/active_record/associations/preloader/through_association.rb +85 -74
- data/lib/active_record/associations/preloader.rb +81 -91
- data/lib/active_record/associations/singular_association.rb +27 -34
- data/lib/active_record/associations/through_association.rb +38 -18
- data/lib/active_record/associations.rb +1732 -1597
- 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 +10 -8
- data/lib/active_record/attribute_methods/dirty.rb +94 -135
- 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 +58 -36
- data/lib/active_record/attribute_methods/write.rb +30 -45
- data/lib/active_record/attribute_methods.rb +166 -109
- data/lib/active_record/attributes.rb +201 -82
- data/lib/active_record/autosave_association.rb +94 -36
- data/lib/active_record/base.rb +57 -44
- 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 +24 -12
- data/lib/active_record/collection_cache_key.rb +53 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +712 -290
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +10 -5
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +237 -90
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +71 -21
- data/lib/active_record/connection_adapters/abstract/quoting.rb +118 -52
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +67 -46
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +318 -217
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +81 -36
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +570 -228
- data/lib/active_record/connection_adapters/abstract/transaction.rb +138 -70
- data/lib/active_record/connection_adapters/abstract_adapter.rb +325 -202
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +542 -601
- 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 +41 -180
- data/lib/active_record/connection_adapters/postgresql/column.rb +35 -11
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +45 -114
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -58
- 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 +4 -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 -22
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -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 -5
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +55 -53
- 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 +462 -284
- 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 +432 -323
- 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 -308
- 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 +178 -198
- data/lib/active_record/counter_cache.rb +79 -36
- data/lib/active_record/define_callbacks.rb +22 -0
- data/lib/active_record/dynamic_matchers.rb +87 -105
- data/lib/active_record/enum.rb +135 -88
- data/lib/active_record/errors.rb +179 -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 +10 -5
- data/lib/active_record/fixture_set/file.rb +35 -9
- data/lib/active_record/fixtures.rb +188 -132
- 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 +21 -3
- data/lib/active_record/locale/en.yml +3 -2
- data/lib/active_record/locking/optimistic.rb +88 -96
- 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 +581 -282
- data/lib/active_record/model_schema.rb +290 -111
- data/lib/active_record/nested_attributes.rb +264 -222
- data/lib/active_record/no_touching.rb +7 -1
- data/lib/active_record/null_relation.rb +24 -37
- data/lib/active_record/persistence.rb +347 -119
- data/lib/active_record/query_cache.rb +13 -24
- data/lib/active_record/querying.rb +19 -17
- data/lib/active_record/railtie.rb +94 -32
- 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 +149 -156
- data/lib/active_record/readonly_attributes.rb +5 -4
- data/lib/active_record/reflection.rb +414 -267
- 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 +256 -248
- data/lib/active_record/relation/delegation.rb +67 -60
- data/lib/active_record/relation/finder_methods.rb +288 -239
- data/lib/active_record/relation/from_clause.rb +26 -0
- data/lib/active_record/relation/merger.rb +86 -86
- data/lib/active_record/relation/predicate_builder/array_handler.rb +24 -24
- 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 +116 -119
- data/lib/active_record/relation/query_attribute.rb +45 -0
- data/lib/active_record/relation/query_methods.rb +448 -393
- data/lib/active_record/relation/record_fetch_warning.rb +51 -0
- data/lib/active_record/relation/spawn_methods.rb +11 -13
- 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 -340
- 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 -16
- data/lib/active_record/scoping/default.rb +102 -85
- 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 +134 -96
- data/lib/active_record/tasks/mysql_database_tasks.rb +56 -100
- data/lib/active_record/tasks/postgresql_database_tasks.rb +83 -41
- 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 +199 -124
- 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 -45
- data/lib/active_record/type/date_time.rb +4 -49
- data/lib/active_record/type/decimal_without_scale.rb +6 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
- 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 +24 -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 +40 -41
- data/lib/active_record/validations.rb +38 -35
- data/lib/active_record/version.rb +3 -1
- data/lib/active_record.rb +34 -22
- 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 -3
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +8 -1
- 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/model/templates/{module.rb → module.rb.tt} +0 -0
- data/lib/rails/generators/active_record.rb +7 -5
- metadata +72 -49
- 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 -163
- data/lib/active_record/attribute_set/builder.rb +0 -106
- data/lib/active_record/attribute_set.rb +0 -81
- data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -498
- 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 -31
- data/lib/active_record/type/decimal.rb +0 -64
- 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 -59
- 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 -40
- data/lib/active_record/type/time_value.rb +0 -38
- data/lib/active_record/type/value.rb +0 -110
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,30 @@ 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
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
92
|
-
Implicit join references were removed with Rails 4.1.
|
93
|
-
Make sure to remove this configuration because it does nothing.
|
94
|
-
MSG
|
95
|
-
end
|
126
|
+
mattr_accessor :belongs_to_required_by_default, instance_accessor: false
|
96
127
|
|
97
128
|
class_attribute :default_connection_handler, instance_writer: false
|
98
|
-
class_attribute :find_by_statement_cache
|
99
129
|
|
100
130
|
def self.connection_handler
|
101
131
|
ActiveRecord::RuntimeRegistry.connection_handler || default_connection_handler
|
@@ -108,17 +138,18 @@ module ActiveRecord
|
|
108
138
|
self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new
|
109
139
|
end
|
110
140
|
|
111
|
-
module ClassMethods
|
141
|
+
module ClassMethods # :nodoc:
|
112
142
|
def allocate
|
113
143
|
define_attribute_methods
|
114
144
|
super
|
115
145
|
end
|
116
146
|
|
117
147
|
def initialize_find_by_cache # :nodoc:
|
118
|
-
|
148
|
+
@find_by_statement_cache = { true => Concurrent::Map.new, false => Concurrent::Map.new }
|
119
149
|
end
|
120
150
|
|
121
151
|
def inherited(child_class) # :nodoc:
|
152
|
+
# initialize cache at class definition for thread safety
|
122
153
|
child_class.initialize_find_by_cache
|
123
154
|
super
|
124
155
|
end
|
@@ -126,74 +157,64 @@ module ActiveRecord
|
|
126
157
|
def find(*ids) # :nodoc:
|
127
158
|
# We don't have cache keys for this stuff yet
|
128
159
|
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
160
|
return super if block_given? ||
|
132
161
|
primary_key.nil? ||
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
id = id.id
|
141
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
142
|
-
You are passing an instance of ActiveRecord::Base to `find`.
|
143
|
-
Please pass the id of the object by calling `.id`
|
144
|
-
MSG
|
145
|
-
end
|
162
|
+
scope_attributes? ||
|
163
|
+
columns_hash.include?(inheritance_column)
|
164
|
+
|
165
|
+
id = ids.first
|
166
|
+
|
167
|
+
return super if StatementCache.unsupported_value?(id)
|
168
|
+
|
146
169
|
key = primary_key
|
147
170
|
|
148
|
-
|
149
|
-
|
150
|
-
where(key => params.bind).limit(1)
|
151
|
-
}
|
171
|
+
statement = cached_find_by_statement(key) { |params|
|
172
|
+
where(key => params.bind).limit(1)
|
152
173
|
}
|
153
|
-
|
174
|
+
|
175
|
+
record = statement.execute([id], connection).first
|
154
176
|
unless record
|
155
|
-
raise RecordNotFound
|
177
|
+
raise RecordNotFound.new("Couldn't find #{name} with '#{primary_key}'=#{id}",
|
178
|
+
name, primary_key, id)
|
156
179
|
end
|
157
180
|
record
|
158
|
-
rescue RangeError
|
159
|
-
raise RecordNotFound
|
181
|
+
rescue ::RangeError
|
182
|
+
raise RecordNotFound.new("Couldn't find #{name} with an out of range value for '#{primary_key}'",
|
183
|
+
name, primary_key)
|
160
184
|
end
|
161
185
|
|
162
186
|
def find_by(*args) # :nodoc:
|
163
|
-
return super if
|
164
|
-
|
187
|
+
return super if scope_attributes? || reflect_on_all_aggregations.any? ||
|
188
|
+
columns_hash.key?(inheritance_column) && base_class != self
|
165
189
|
|
166
190
|
hash = args.first
|
167
191
|
|
168
|
-
return super if hash.values.any? { |v|
|
169
|
-
|
192
|
+
return super if !(Hash === hash) || hash.values.any? { |v|
|
193
|
+
StatementCache.unsupported_value?(v)
|
170
194
|
}
|
171
195
|
|
172
196
|
# We can't cache Post.find_by(author: david) ...yet
|
173
197
|
return super unless hash.keys.all? { |k| columns_hash.has_key?(k.to_s) }
|
174
198
|
|
175
|
-
|
199
|
+
keys = hash.keys
|
176
200
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
wheres = key.each_with_object({}) { |param,o|
|
181
|
-
o[param] = params.bind
|
182
|
-
}
|
183
|
-
klass.where(wheres).limit(1)
|
201
|
+
statement = cached_find_by_statement(keys) { |params|
|
202
|
+
wheres = keys.each_with_object({}) { |param, o|
|
203
|
+
o[param] = params.bind
|
184
204
|
}
|
205
|
+
where(wheres).limit(1)
|
185
206
|
}
|
186
207
|
begin
|
187
|
-
|
188
|
-
rescue TypeError
|
189
|
-
raise ActiveRecord::StatementInvalid
|
190
|
-
rescue RangeError
|
208
|
+
statement.execute(hash.values, connection).first
|
209
|
+
rescue TypeError
|
210
|
+
raise ActiveRecord::StatementInvalid
|
211
|
+
rescue ::RangeError
|
191
212
|
nil
|
192
213
|
end
|
193
214
|
end
|
194
215
|
|
195
216
|
def find_by!(*args) # :nodoc:
|
196
|
-
find_by(*args)
|
217
|
+
find_by(*args) || raise(RecordNotFound.new("Couldn't find #{name}", name))
|
197
218
|
end
|
198
219
|
|
199
220
|
def initialize_generated_modules # :nodoc:
|
@@ -203,7 +224,9 @@ module ActiveRecord
|
|
203
224
|
def generated_association_methods
|
204
225
|
@generated_association_methods ||= begin
|
205
226
|
mod = const_set(:GeneratedAssociationMethods, Module.new)
|
227
|
+
private_constant :GeneratedAssociationMethods
|
206
228
|
include mod
|
229
|
+
|
207
230
|
mod
|
208
231
|
end
|
209
232
|
end
|
@@ -217,14 +240,14 @@ module ActiveRecord
|
|
217
240
|
elsif !connected?
|
218
241
|
"#{super} (call '#{super}.connection' to establish a connection)"
|
219
242
|
elsif table_exists?
|
220
|
-
attr_list =
|
243
|
+
attr_list = attribute_types.map { |name, type| "#{name}: #{type.type}" } * ", "
|
221
244
|
"#{super}(#{attr_list})"
|
222
245
|
else
|
223
246
|
"#{super}(Table doesn't exist)"
|
224
247
|
end
|
225
248
|
end
|
226
249
|
|
227
|
-
# Overwrite the default class equality method to provide support for
|
250
|
+
# Overwrite the default class equality method to provide support for decorated models.
|
228
251
|
def ===(object)
|
229
252
|
object.is_a?(self)
|
230
253
|
end
|
@@ -232,33 +255,46 @@ module ActiveRecord
|
|
232
255
|
# Returns an instance of <tt>Arel::Table</tt> loaded with the current table name.
|
233
256
|
#
|
234
257
|
# class Post < ActiveRecord::Base
|
235
|
-
# scope :published_and_commented, -> { published.and(
|
258
|
+
# scope :published_and_commented, -> { published.and(arel_table[:comments_count].gt(0)) }
|
236
259
|
# end
|
237
260
|
def arel_table # :nodoc:
|
238
|
-
@arel_table ||= Arel::Table.new(table_name,
|
261
|
+
@arel_table ||= Arel::Table.new(table_name, type_caster: type_caster)
|
239
262
|
end
|
240
263
|
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
264
|
+
def arel_attribute(name, table = arel_table) # :nodoc:
|
265
|
+
name = attribute_alias(name) if attribute_alias?(name)
|
266
|
+
table[name]
|
267
|
+
end
|
268
|
+
|
269
|
+
def predicate_builder # :nodoc:
|
270
|
+
@predicate_builder ||= PredicateBuilder.new(table_metadata)
|
271
|
+
end
|
272
|
+
|
273
|
+
def type_caster # :nodoc:
|
274
|
+
TypeCaster::Map.new(self)
|
249
275
|
end
|
250
276
|
|
251
277
|
private
|
252
278
|
|
253
|
-
|
254
|
-
|
279
|
+
def cached_find_by_statement(key, &block)
|
280
|
+
cache = @find_by_statement_cache[connection.prepared_statements]
|
281
|
+
cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
|
282
|
+
end
|
283
|
+
|
284
|
+
def relation
|
285
|
+
relation = Relation.create(self)
|
255
286
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
287
|
+
if finder_needs_type_condition? && !ignore_default_scope?
|
288
|
+
relation.where!(type_condition)
|
289
|
+
relation.create_with!(inheritance_column.to_s => sti_name)
|
290
|
+
else
|
291
|
+
relation
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
def table_metadata
|
296
|
+
TableMetadata.new(self, arel_table)
|
260
297
|
end
|
261
|
-
end
|
262
298
|
end
|
263
299
|
|
264
300
|
# New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
|
@@ -269,16 +305,14 @@ module ActiveRecord
|
|
269
305
|
# ==== Example:
|
270
306
|
# # Instantiates a single new object
|
271
307
|
# User.new(first_name: 'Jamie')
|
272
|
-
def initialize(attributes = nil
|
273
|
-
@attributes = self.class._default_attributes.dup
|
308
|
+
def initialize(attributes = nil)
|
274
309
|
self.class.define_attribute_methods
|
310
|
+
@attributes = self.class._default_attributes.deep_dup
|
275
311
|
|
276
312
|
init_internals
|
277
313
|
initialize_internals_callback
|
278
314
|
|
279
|
-
|
280
|
-
# Remove it when we drop support to this gem.
|
281
|
-
init_attributes(attributes, options) if attributes
|
315
|
+
assign_attributes(attributes) if attributes
|
282
316
|
|
283
317
|
yield self if block_given?
|
284
318
|
_run_initialize_callbacks
|
@@ -286,7 +320,7 @@ module ActiveRecord
|
|
286
320
|
|
287
321
|
# Initialize an empty model object from +coder+. +coder+ should be
|
288
322
|
# the result of previously encoding an Active Record model, using
|
289
|
-
#
|
323
|
+
# #encode_with.
|
290
324
|
#
|
291
325
|
# class Post < ActiveRecord::Base
|
292
326
|
# end
|
@@ -300,14 +334,16 @@ module ActiveRecord
|
|
300
334
|
# post.title # => 'hello world'
|
301
335
|
def init_with(coder)
|
302
336
|
coder = LegacyYamlAdapter.convert(self.class, coder)
|
303
|
-
@attributes = coder
|
337
|
+
@attributes = self.class.yaml_encoder.decode(coder)
|
304
338
|
|
305
339
|
init_internals
|
306
340
|
|
307
|
-
@new_record = coder[
|
341
|
+
@new_record = coder["new_record"]
|
308
342
|
|
309
343
|
self.class.define_attribute_methods
|
310
344
|
|
345
|
+
yield self if block_given?
|
346
|
+
|
311
347
|
_run_find_callbacks
|
312
348
|
_run_initialize_callbacks
|
313
349
|
|
@@ -342,23 +378,22 @@ module ActiveRecord
|
|
342
378
|
|
343
379
|
##
|
344
380
|
def initialize_dup(other) # :nodoc:
|
345
|
-
@attributes = @attributes.
|
381
|
+
@attributes = @attributes.deep_dup
|
346
382
|
@attributes.reset(self.class.primary_key)
|
347
383
|
|
348
384
|
_run_initialize_callbacks
|
349
385
|
|
350
|
-
@
|
351
|
-
@
|
352
|
-
|
353
|
-
@
|
354
|
-
@destroyed = false
|
386
|
+
@new_record = true
|
387
|
+
@destroyed = false
|
388
|
+
@_start_transaction_state = {}
|
389
|
+
@transaction_state = nil
|
355
390
|
|
356
391
|
super
|
357
392
|
end
|
358
393
|
|
359
394
|
# Populate +coder+ with attributes about this record that should be
|
360
395
|
# serialized. The structure of +coder+ defined in this method is
|
361
|
-
# guaranteed to match the structure of +coder+ passed to the
|
396
|
+
# guaranteed to match the structure of +coder+ passed to the #init_with
|
362
397
|
# method.
|
363
398
|
#
|
364
399
|
# Example:
|
@@ -369,11 +404,9 @@ module ActiveRecord
|
|
369
404
|
# Post.new.encode_with(coder)
|
370
405
|
# coder # => {"attributes" => {"id" => nil, ... }}
|
371
406
|
def encode_with(coder)
|
372
|
-
|
373
|
-
coder[
|
374
|
-
coder[
|
375
|
-
coder['new_record'] = new_record?
|
376
|
-
coder['active_record_yaml_version'] = 0
|
407
|
+
self.class.yaml_encoder.encode(@attributes, coder)
|
408
|
+
coder["new_record"] = new_record?
|
409
|
+
coder["active_record_yaml_version"] = 2
|
377
410
|
end
|
378
411
|
|
379
412
|
# Returns true if +comparison_object+ is the same exact object, or +comparison_object+
|
@@ -397,7 +430,7 @@ module ActiveRecord
|
|
397
430
|
# [ Person.find(1), Person.find(2), Person.find(3) ] & [ Person.find(1), Person.find(4) ] # => [ Person.find(1) ]
|
398
431
|
def hash
|
399
432
|
if id
|
400
|
-
id.hash
|
433
|
+
self.class.hash ^ id.hash
|
401
434
|
else
|
402
435
|
super
|
403
436
|
end
|
@@ -419,7 +452,7 @@ module ActiveRecord
|
|
419
452
|
# Allows sort on objects
|
420
453
|
def <=>(other_object)
|
421
454
|
if other_object.is_a?(self.class)
|
422
|
-
|
455
|
+
to_key <=> other_object.to_key
|
423
456
|
else
|
424
457
|
super
|
425
458
|
end
|
@@ -445,135 +478,82 @@ module ActiveRecord
|
|
445
478
|
# We check defined?(@attributes) not to issue warnings if the object is
|
446
479
|
# allocated but not initialized.
|
447
480
|
inspection = if defined?(@attributes) && @attributes
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
481
|
+
self.class.attribute_names.collect do |name|
|
482
|
+
if has_attribute?(name)
|
483
|
+
"#{name}: #{attribute_for_inspect(name)}"
|
484
|
+
end
|
485
|
+
end.compact.join(", ")
|
486
|
+
else
|
487
|
+
"not initialized"
|
488
|
+
end
|
489
|
+
|
456
490
|
"#<#{self.class} #{inspection}>"
|
457
491
|
end
|
458
492
|
|
459
|
-
# Takes a PP and prettily prints this record to it, allowing you to get a nice result from
|
493
|
+
# Takes a PP and prettily prints this record to it, allowing you to get a nice result from <tt>pp record</tt>
|
460
494
|
# when pp is required.
|
461
495
|
def pretty_print(pp)
|
462
496
|
return super if custom_inspect_method_defined?
|
463
497
|
pp.object_address_group(self) do
|
464
498
|
if defined?(@attributes) && @attributes
|
465
499
|
column_names = self.class.column_names.select { |name| has_attribute?(name) || new_record? }
|
466
|
-
pp.seplist(column_names, proc { pp.text
|
500
|
+
pp.seplist(column_names, proc { pp.text "," }) do |column_name|
|
467
501
|
column_value = read_attribute(column_name)
|
468
|
-
pp.breakable
|
502
|
+
pp.breakable " "
|
469
503
|
pp.group(1) do
|
470
504
|
pp.text column_name
|
471
|
-
pp.text
|
505
|
+
pp.text ":"
|
472
506
|
pp.breakable
|
473
507
|
pp.pp column_value
|
474
508
|
end
|
475
509
|
end
|
476
510
|
else
|
477
|
-
pp.breakable
|
478
|
-
pp.text
|
511
|
+
pp.breakable " "
|
512
|
+
pp.text "not initialized"
|
479
513
|
end
|
480
514
|
end
|
481
515
|
end
|
482
516
|
|
483
517
|
# Returns a hash of the given methods with their names as keys and returned values as values.
|
484
518
|
def slice(*methods)
|
485
|
-
Hash[methods.map! { |method| [method, public_send(method)] }].with_indifferent_access
|
519
|
+
Hash[methods.flatten.map! { |method| [method, public_send(method)] }].with_indifferent_access
|
486
520
|
end
|
487
521
|
|
488
522
|
private
|
489
523
|
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
#
|
502
|
-
# The @transaction_state variable stores the states of the associated
|
503
|
-
# transaction. This relies on the fact that a transaction can only be in
|
504
|
-
# one rollback or commit (otherwise a list of states would be required)
|
505
|
-
# Each AR object inside of a transaction carries that transaction's
|
506
|
-
# TransactionState.
|
507
|
-
#
|
508
|
-
# This method checks to see if the ActiveRecord object's state reflects
|
509
|
-
# the TransactionState, and rolls back or commits the ActiveRecord object
|
510
|
-
# as appropriate.
|
511
|
-
#
|
512
|
-
# Since ActiveRecord objects can be inside multiple transactions, this
|
513
|
-
# method recursively goes through the parent of the TransactionState and
|
514
|
-
# checks if the ActiveRecord object reflects the state of the object.
|
515
|
-
def sync_with_transaction_state
|
516
|
-
update_attributes_from_transaction_state(@transaction_state, 0)
|
517
|
-
end
|
524
|
+
# +Array#flatten+ will call +#to_ary+ (recursively) on each of the elements of
|
525
|
+
# the array, and then rescues from the possible +NoMethodError+. If those elements are
|
526
|
+
# +ActiveRecord::Base+'s, then this triggers the various +method_missing+'s that we have,
|
527
|
+
# which significantly impacts upon performance.
|
528
|
+
#
|
529
|
+
# So we can avoid the +method_missing+ hit by explicitly defining +#to_ary+ as +nil+ here.
|
530
|
+
#
|
531
|
+
# See also https://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary.html
|
532
|
+
def to_ary
|
533
|
+
nil
|
534
|
+
end
|
518
535
|
|
519
|
-
|
520
|
-
|
536
|
+
def init_internals
|
537
|
+
@readonly = false
|
538
|
+
@destroyed = false
|
539
|
+
@marked_for_destruction = false
|
540
|
+
@destroyed_by_association = nil
|
541
|
+
@new_record = true
|
542
|
+
@_start_transaction_state = {}
|
543
|
+
@transaction_state = nil
|
544
|
+
end
|
521
545
|
|
522
|
-
|
523
|
-
|
524
|
-
restore_transaction_record_state if transaction_state.rolledback?
|
525
|
-
clear_transaction_record_state
|
526
|
-
@reflects_state[depth] = true
|
527
|
-
end
|
546
|
+
def initialize_internals_callback
|
547
|
+
end
|
528
548
|
|
529
|
-
|
530
|
-
|
549
|
+
def thaw
|
550
|
+
if frozen?
|
551
|
+
@attributes = @attributes.dup
|
531
552
|
end
|
532
553
|
end
|
533
|
-
end
|
534
|
-
|
535
|
-
# Under Ruby 1.9, Array#flatten will call #to_ary (recursively) on each of the elements
|
536
|
-
# of the array, and then rescues from the possible NoMethodError. If those elements are
|
537
|
-
# ActiveRecord::Base's, then this triggers the various method_missing's that we have,
|
538
|
-
# which significantly impacts upon performance.
|
539
|
-
#
|
540
|
-
# So we can avoid the method_missing hit by explicitly defining #to_ary as nil here.
|
541
|
-
#
|
542
|
-
# See also http://tenderlovemaking.com/2011/06/28/til-its-ok-to-return-nil-from-to_ary.html
|
543
|
-
def to_ary # :nodoc:
|
544
|
-
nil
|
545
|
-
end
|
546
|
-
|
547
|
-
def init_internals
|
548
|
-
@aggregation_cache = {}
|
549
|
-
@association_cache = {}
|
550
|
-
@readonly = false
|
551
|
-
@destroyed = false
|
552
|
-
@marked_for_destruction = false
|
553
|
-
@destroyed_by_association = nil
|
554
|
-
@new_record = true
|
555
|
-
@txn = nil
|
556
|
-
@_start_transaction_state = {}
|
557
|
-
@transaction_state = nil
|
558
|
-
end
|
559
|
-
|
560
|
-
def initialize_internals_callback
|
561
|
-
end
|
562
554
|
|
563
|
-
|
564
|
-
|
565
|
-
def init_attributes(attributes, options)
|
566
|
-
assign_attributes(attributes)
|
567
|
-
end
|
568
|
-
|
569
|
-
def thaw
|
570
|
-
if frozen?
|
571
|
-
@attributes = @attributes.dup
|
555
|
+
def custom_inspect_method_defined?
|
556
|
+
self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner
|
572
557
|
end
|
573
|
-
end
|
574
|
-
|
575
|
-
def custom_inspect_method_defined?
|
576
|
-
self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner
|
577
|
-
end
|
578
558
|
end
|
579
559
|
end
|