activerecord 7.1.3.4 → 7.2.2.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 +652 -2032
- data/README.rdoc +15 -15
- data/examples/performance.rb +2 -2
- data/lib/active_record/association_relation.rb +1 -1
- data/lib/active_record/associations/alias_tracker.rb +25 -19
- data/lib/active_record/associations/association.rb +15 -8
- data/lib/active_record/associations/belongs_to_association.rb +18 -11
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
- data/lib/active_record/associations/builder/belongs_to.rb +1 -0
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +2 -2
- data/lib/active_record/associations/builder/has_many.rb +3 -4
- data/lib/active_record/associations/builder/has_one.rb +3 -4
- data/lib/active_record/associations/collection_association.rb +11 -5
- data/lib/active_record/associations/collection_proxy.rb +14 -1
- data/lib/active_record/associations/errors.rb +265 -0
- data/lib/active_record/associations/has_many_association.rb +3 -3
- data/lib/active_record/associations/has_many_through_association.rb +7 -1
- data/lib/active_record/associations/has_one_association.rb +2 -2
- data/lib/active_record/associations/join_dependency/join_association.rb +30 -27
- data/lib/active_record/associations/join_dependency.rb +10 -12
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +2 -1
- data/lib/active_record/associations/preloader/branch.rb +7 -1
- data/lib/active_record/associations/preloader/through_association.rb +1 -3
- data/lib/active_record/associations/singular_association.rb +6 -0
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +62 -289
- data/lib/active_record/attribute_assignment.rb +0 -2
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/dirty.rb +2 -2
- data/lib/active_record/attribute_methods/primary_key.rb +23 -55
- data/lib/active_record/attribute_methods/read.rb +4 -16
- data/lib/active_record/attribute_methods/serialization.rb +4 -24
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +11 -6
- data/lib/active_record/attribute_methods/write.rb +3 -3
- data/lib/active_record/attribute_methods.rb +89 -58
- data/lib/active_record/attributes.rb +61 -47
- data/lib/active_record/autosave_association.rb +17 -31
- data/lib/active_record/base.rb +2 -3
- data/lib/active_record/callbacks.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +24 -107
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +1 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +270 -58
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +35 -18
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +190 -75
- data/lib/active_record/connection_adapters/abstract/quoting.rb +65 -91
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +23 -10
- data/lib/active_record/connection_adapters/abstract/transaction.rb +125 -62
- data/lib/active_record/connection_adapters/abstract_adapter.rb +38 -59
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +73 -19
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +9 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +43 -48
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +8 -1
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +16 -15
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +20 -32
- data/lib/active_record/connection_adapters/pool_config.rb +7 -6
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +27 -4
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +58 -58
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +20 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +18 -12
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +29 -24
- data/lib/active_record/connection_adapters/schema_cache.rb +123 -128
- data/lib/active_record/connection_adapters/sqlite3/column.rb +14 -1
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +10 -6
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +44 -46
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +13 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +25 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +127 -77
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +15 -15
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +32 -65
- data/lib/active_record/connection_adapters.rb +121 -0
- data/lib/active_record/connection_handling.rb +56 -41
- data/lib/active_record/core.rb +93 -40
- data/lib/active_record/counter_cache.rb +23 -10
- data/lib/active_record/database_configurations/connection_url_resolver.rb +8 -3
- data/lib/active_record/database_configurations/database_config.rb +19 -4
- data/lib/active_record/database_configurations/hash_config.rb +44 -36
- data/lib/active_record/database_configurations/url_config.rb +20 -1
- data/lib/active_record/database_configurations.rb +1 -1
- data/lib/active_record/delegated_type.rb +30 -6
- data/lib/active_record/destroy_association_async_job.rb +1 -1
- data/lib/active_record/dynamic_matchers.rb +2 -2
- data/lib/active_record/encryption/encryptable_record.rb +3 -3
- data/lib/active_record/encryption/encrypted_attribute_type.rb +26 -6
- data/lib/active_record/encryption/encryptor.rb +18 -3
- data/lib/active_record/encryption/key_provider.rb +1 -1
- data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
- data/lib/active_record/encryption/message_serializer.rb +4 -0
- data/lib/active_record/encryption/null_encryptor.rb +4 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
- data/lib/active_record/encryption/scheme.rb +8 -4
- data/lib/active_record/encryption.rb +2 -0
- data/lib/active_record/enum.rb +19 -2
- data/lib/active_record/errors.rb +46 -20
- data/lib/active_record/explain.rb +13 -24
- data/lib/active_record/fixtures.rb +37 -31
- data/lib/active_record/future_result.rb +17 -4
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +4 -2
- data/lib/active_record/insert_all.rb +18 -15
- data/lib/active_record/integration.rb +4 -1
- data/lib/active_record/internal_metadata.rb +48 -34
- data/lib/active_record/locking/optimistic.rb +8 -7
- data/lib/active_record/log_subscriber.rb +0 -21
- data/lib/active_record/marshalling.rb +4 -1
- data/lib/active_record/message_pack.rb +2 -2
- data/lib/active_record/migration/command_recorder.rb +2 -3
- data/lib/active_record/migration/compatibility.rb +11 -3
- data/lib/active_record/migration/default_strategy.rb +4 -5
- data/lib/active_record/migration/pending_migration_connection.rb +2 -2
- data/lib/active_record/migration.rb +85 -76
- data/lib/active_record/model_schema.rb +38 -70
- data/lib/active_record/nested_attributes.rb +24 -5
- data/lib/active_record/normalization.rb +3 -7
- data/lib/active_record/persistence.rb +32 -354
- data/lib/active_record/query_cache.rb +19 -8
- data/lib/active_record/query_logs.rb +15 -0
- data/lib/active_record/query_logs_formatter.rb +1 -1
- data/lib/active_record/querying.rb +21 -9
- data/lib/active_record/railtie.rb +50 -68
- data/lib/active_record/railties/controller_runtime.rb +13 -4
- data/lib/active_record/railties/databases.rake +42 -45
- data/lib/active_record/reflection.rb +106 -38
- data/lib/active_record/relation/batches/batch_enumerator.rb +15 -2
- data/lib/active_record/relation/batches.rb +14 -8
- data/lib/active_record/relation/calculations.rb +96 -63
- data/lib/active_record/relation/delegation.rb +8 -11
- data/lib/active_record/relation/finder_methods.rb +16 -2
- data/lib/active_record/relation/merger.rb +4 -6
- data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +9 -3
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +6 -1
- data/lib/active_record/relation/predicate_builder.rb +3 -3
- data/lib/active_record/relation/query_methods.rb +245 -65
- data/lib/active_record/relation/record_fetch_warning.rb +3 -0
- data/lib/active_record/relation/spawn_methods.rb +2 -18
- data/lib/active_record/relation/where_clause.rb +7 -19
- data/lib/active_record/relation.rb +500 -66
- data/lib/active_record/result.rb +32 -45
- data/lib/active_record/runtime_registry.rb +39 -0
- data/lib/active_record/sanitization.rb +24 -19
- data/lib/active_record/schema.rb +8 -6
- data/lib/active_record/schema_dumper.rb +19 -9
- data/lib/active_record/schema_migration.rb +30 -14
- data/lib/active_record/scoping/named.rb +1 -0
- data/lib/active_record/signed_id.rb +20 -1
- data/lib/active_record/statement_cache.rb +7 -7
- data/lib/active_record/table_metadata.rb +1 -10
- data/lib/active_record/tasks/database_tasks.rb +98 -48
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -1
- data/lib/active_record/test_fixtures.rb +87 -89
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +5 -3
- data/lib/active_record/token_for.rb +22 -12
- data/lib/active_record/touch_later.rb +1 -1
- data/lib/active_record/transaction.rb +132 -0
- data/lib/active_record/transactions.rb +70 -14
- data/lib/active_record/translation.rb +0 -2
- data/lib/active_record/type/serialized.rb +1 -3
- data/lib/active_record/type_caster/connection.rb +4 -4
- data/lib/active_record/validations/associated.rb +9 -3
- data/lib/active_record/validations/uniqueness.rb +15 -10
- data/lib/active_record/validations.rb +4 -1
- data/lib/active_record.rb +150 -41
- data/lib/arel/alias_predication.rb +1 -1
- data/lib/arel/collectors/bind.rb +2 -0
- data/lib/arel/collectors/composite.rb +7 -0
- data/lib/arel/collectors/sql_string.rb +1 -1
- data/lib/arel/collectors/substitute_binds.rb +1 -1
- data/lib/arel/nodes/binary.rb +0 -6
- data/lib/arel/nodes/bound_sql_literal.rb +9 -5
- data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
- data/lib/arel/nodes/node.rb +4 -3
- data/lib/arel/nodes/sql_literal.rb +7 -0
- data/lib/arel/nodes.rb +2 -2
- data/lib/arel/predications.rb +1 -1
- data/lib/arel/select_manager.rb +1 -1
- data/lib/arel/tree_manager.rb +8 -3
- data/lib/arel/update_manager.rb +2 -1
- data/lib/arel/visitors/dot.rb +1 -0
- data/lib/arel/visitors/mysql.rb +9 -4
- data/lib/arel/visitors/postgresql.rb +1 -12
- data/lib/arel/visitors/sqlite.rb +25 -0
- data/lib/arel/visitors/to_sql.rb +31 -17
- data/lib/arel.rb +7 -3
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
- metadata +21 -15
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "mutex_m"
|
4
3
|
require "active_support/core_ext/module/delegation"
|
5
4
|
|
6
5
|
module ActiveRecord
|
@@ -67,23 +66,22 @@ module ActiveRecord
|
|
67
66
|
end
|
68
67
|
|
69
68
|
class GeneratedRelationMethods < Module # :nodoc:
|
70
|
-
|
69
|
+
MUTEX = Mutex.new
|
71
70
|
|
72
71
|
def generate_method(method)
|
73
|
-
synchronize do
|
72
|
+
MUTEX.synchronize do
|
74
73
|
return if method_defined?(method)
|
75
74
|
|
76
|
-
if /\A[a-zA-Z_]\w*[!?]?\z/.match?(method) &&
|
75
|
+
if /\A[a-zA-Z_]\w*[!?]?\z/.match?(method) && !::ActiveSupport::Delegation::RESERVED_METHOD_NAMES.include?(method.to_s)
|
77
76
|
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
78
77
|
def #{method}(...)
|
79
78
|
scoping { klass.#{method}(...) }
|
80
79
|
end
|
81
80
|
RUBY
|
82
81
|
else
|
83
|
-
define_method(method) do |*args, &block|
|
84
|
-
scoping { klass.public_send(method, *args, &block) }
|
82
|
+
define_method(method) do |*args, **kwargs, &block|
|
83
|
+
scoping { klass.public_send(method, *args, **kwargs, &block) }
|
85
84
|
end
|
86
|
-
ruby2_keywords(method)
|
87
85
|
end
|
88
86
|
end
|
89
87
|
end
|
@@ -102,7 +100,7 @@ module ActiveRecord
|
|
102
100
|
:to_sentence, :to_fs, :to_formatted_s, :as_json,
|
103
101
|
:shuffle, :split, :slice, :index, :rindex, to: :records
|
104
102
|
|
105
|
-
delegate :primary_key, :connection, :transaction, to: :klass
|
103
|
+
delegate :primary_key, :lease_connection, :connection, :with_connection, :transaction, to: :klass
|
106
104
|
|
107
105
|
module ClassSpecificRelation # :nodoc:
|
108
106
|
extend ActiveSupport::Concern
|
@@ -114,17 +112,16 @@ module ActiveRecord
|
|
114
112
|
end
|
115
113
|
|
116
114
|
private
|
117
|
-
def method_missing(method,
|
115
|
+
def method_missing(method, ...)
|
118
116
|
if @klass.respond_to?(method)
|
119
117
|
unless Delegation.uncacheable_methods.include?(method)
|
120
118
|
@klass.generate_relation_method(method)
|
121
119
|
end
|
122
|
-
scoping { @klass.public_send(method,
|
120
|
+
scoping { @klass.public_send(method, ...) }
|
123
121
|
else
|
124
122
|
super
|
125
123
|
end
|
126
124
|
end
|
127
|
-
ruby2_keywords(:method_missing)
|
128
125
|
end
|
129
126
|
|
130
127
|
module ClassMethods # :nodoc:
|
@@ -87,6 +87,14 @@ module ActiveRecord
|
|
87
87
|
#
|
88
88
|
# Person.where(name: 'Spartacus', rating: 4).pluck(:field1, :field2)
|
89
89
|
# # returns an Array of the required fields.
|
90
|
+
#
|
91
|
+
# ==== Edge Cases
|
92
|
+
#
|
93
|
+
# Person.find(37) # raises ActiveRecord::RecordNotFound exception if the record with the given ID does not exist.
|
94
|
+
# Person.find([37]) # raises ActiveRecord::RecordNotFound exception if the record with the given ID in the input array does not exist.
|
95
|
+
# Person.find(nil) # raises ActiveRecord::RecordNotFound exception if the argument is nil.
|
96
|
+
# Person.find([]) # returns an empty array if the argument is an empty array.
|
97
|
+
# Person.find # raises ActiveRecord::RecordNotFound exception if the argument is not provided.
|
90
98
|
def find(*args)
|
91
99
|
return super if block_given?
|
92
100
|
find_with_ids(*args)
|
@@ -366,7 +374,11 @@ module ActiveRecord
|
|
366
374
|
relation = construct_relation_for_exists(conditions)
|
367
375
|
return false if relation.where_clause.contradiction?
|
368
376
|
|
369
|
-
skip_query_cache_if_necessary
|
377
|
+
skip_query_cache_if_necessary do
|
378
|
+
with_connection do |c|
|
379
|
+
c.select_rows(relation.arel, "#{name} Exists?").size == 1
|
380
|
+
end
|
381
|
+
end
|
370
382
|
end
|
371
383
|
|
372
384
|
# Returns true if the relation contains the given record or false otherwise.
|
@@ -459,7 +471,9 @@ module ActiveRecord
|
|
459
471
|
)
|
460
472
|
)
|
461
473
|
relation = skip_query_cache_if_necessary do
|
462
|
-
klass.
|
474
|
+
klass.with_connection do |c|
|
475
|
+
c.distinct_relation_for_primary_key(relation)
|
476
|
+
end
|
463
477
|
end
|
464
478
|
end
|
465
479
|
|
@@ -7,16 +7,15 @@ module ActiveRecord
|
|
7
7
|
class HashMerger # :nodoc:
|
8
8
|
attr_reader :relation, :hash
|
9
9
|
|
10
|
-
def initialize(relation, hash
|
10
|
+
def initialize(relation, hash)
|
11
11
|
hash.assert_valid_keys(*Relation::VALUE_METHODS)
|
12
12
|
|
13
13
|
@relation = relation
|
14
14
|
@hash = hash
|
15
|
-
@rewhere = rewhere
|
16
15
|
end
|
17
16
|
|
18
17
|
def merge
|
19
|
-
Merger.new(relation, other
|
18
|
+
Merger.new(relation, other).merge
|
20
19
|
end
|
21
20
|
|
22
21
|
# Applying values to a relation has some side effects. E.g.
|
@@ -44,11 +43,10 @@ module ActiveRecord
|
|
44
43
|
class Merger # :nodoc:
|
45
44
|
attr_reader :relation, :values, :other
|
46
45
|
|
47
|
-
def initialize(relation, other
|
46
|
+
def initialize(relation, other)
|
48
47
|
@relation = relation
|
49
48
|
@values = other.values
|
50
49
|
@other = other
|
51
|
-
@rewhere = rewhere
|
52
50
|
end
|
53
51
|
|
54
52
|
NORMAL_VALUES = Relation::VALUE_METHODS - Relation::CLAUSE_METHODS -
|
@@ -178,7 +176,7 @@ module ActiveRecord
|
|
178
176
|
def merge_clauses
|
179
177
|
relation.from_clause = other.from_clause if replace_from_clause?
|
180
178
|
|
181
|
-
where_clause = relation.where_clause.merge(other.where_clause
|
179
|
+
where_clause = relation.where_clause.merge(other.where_clause)
|
182
180
|
relation.where_clause = where_clause unless where_clause.empty?
|
183
181
|
|
184
182
|
having_clause = relation.having_clause.merge(other.having_clause)
|
@@ -13,7 +13,7 @@ module ActiveRecord
|
|
13
13
|
return attribute.in([]) if value.empty?
|
14
14
|
|
15
15
|
values = value.map { |x| x.is_a?(Base) ? x.id : x }
|
16
|
-
nils = values.
|
16
|
+
nils = values.compact!
|
17
17
|
ranges = values.extract! { |v| v.is_a?(Range) }
|
18
18
|
|
19
19
|
values_predicate =
|
@@ -23,7 +23,7 @@ module ActiveRecord
|
|
23
23
|
else Arel::Nodes::HomogeneousIn.new(values, attribute, :in)
|
24
24
|
end
|
25
25
|
|
26
|
-
|
26
|
+
if nils
|
27
27
|
values_predicate = values_predicate.or(attribute.eq(nil))
|
28
28
|
end
|
29
29
|
|
@@ -57,9 +57,15 @@ module ActiveRecord
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def convert_to_id(value)
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
if primary_key.is_a?(Array)
|
61
|
+
primary_key.map do |attribute|
|
62
|
+
if attribute == "id"
|
63
|
+
value.id_value
|
64
|
+
else
|
65
|
+
value.public_send(attribute)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
elsif value.respond_to?(primary_key)
|
63
69
|
value.public_send(primary_key)
|
64
70
|
else
|
65
71
|
value
|
@@ -43,7 +43,12 @@ module ActiveRecord
|
|
43
43
|
|
44
44
|
def convert_to_id(value)
|
45
45
|
if value.is_a?(Base)
|
46
|
-
|
46
|
+
primary_key = primary_key(value)
|
47
|
+
if primary_key.is_a?(Array)
|
48
|
+
primary_key.map { |column| value._read_attribute(column) }
|
49
|
+
else
|
50
|
+
value._read_attribute(primary_key)
|
51
|
+
end
|
47
52
|
elsif value.is_a?(Relation)
|
48
53
|
value.select(primary_key(value))
|
49
54
|
else
|
@@ -28,9 +28,9 @@ module ActiveRecord
|
|
28
28
|
def self.references(attributes)
|
29
29
|
attributes.each_with_object([]) do |(key, value), result|
|
30
30
|
if value.is_a?(Hash)
|
31
|
-
result << Arel.sql(key)
|
31
|
+
result << Arel.sql(key, retryable: true)
|
32
32
|
elsif (idx = key.rindex("."))
|
33
|
-
result << Arel.sql(key[0, idx])
|
33
|
+
result << Arel.sql(key[0, idx], retryable: true)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
@@ -142,7 +142,7 @@ module ActiveRecord
|
|
142
142
|
queries.first
|
143
143
|
else
|
144
144
|
queries.map! { |query| query.reduce(&:and) }
|
145
|
-
queries =
|
145
|
+
queries = Arel::Nodes::Or.new(queries)
|
146
146
|
Arel::Nodes::Grouping.new(queries)
|
147
147
|
end
|
148
148
|
end
|