activerecord 6.0.0.beta3 → 6.0.0.rc1
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 +286 -6
- data/README.rdoc +3 -1
- data/lib/active_record.rb +0 -1
- data/lib/active_record/associations.rb +3 -2
- data/lib/active_record/associations/association.rb +1 -1
- data/lib/active_record/associations/builder/association.rb +14 -18
- data/lib/active_record/associations/builder/belongs_to.rb +5 -2
- data/lib/active_record/associations/builder/collection_association.rb +3 -13
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +35 -1
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_proxy.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +4 -11
- data/lib/active_record/associations/preloader.rb +11 -6
- data/lib/active_record/associations/preloader/association.rb +32 -30
- data/lib/active_record/associations/preloader/through_association.rb +48 -28
- data/lib/active_record/attribute_methods.rb +4 -3
- data/lib/active_record/attribute_methods/before_type_cast.rb +4 -1
- data/lib/active_record/attribute_methods/dirty.rb +42 -14
- data/lib/active_record/attribute_methods/primary_key.rb +7 -15
- data/lib/active_record/attribute_methods/query.rb +2 -3
- data/lib/active_record/attribute_methods/read.rb +3 -9
- data/lib/active_record/attribute_methods/write.rb +6 -12
- data/lib/active_record/attributes.rb +13 -0
- data/lib/active_record/autosave_association.rb +13 -3
- data/lib/active_record/base.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +1 -0
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +8 -4
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +84 -61
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -1
- data/lib/active_record/connection_adapters/abstract/quoting.rb +10 -6
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +4 -7
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +70 -14
- data/lib/active_record/connection_adapters/abstract_adapter.rb +56 -11
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +65 -69
- data/lib/active_record/connection_adapters/column.rb +17 -13
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +45 -7
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +4 -4
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +9 -6
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +6 -2
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -30
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +5 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +34 -38
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +23 -27
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +57 -27
- data/lib/active_record/connection_adapters/schema_cache.rb +32 -14
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +2 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +50 -112
- data/lib/active_record/connection_handling.rb +17 -10
- data/lib/active_record/core.rb +15 -20
- data/lib/active_record/database_configurations.rb +14 -14
- data/lib/active_record/database_configurations/hash_config.rb +11 -11
- data/lib/active_record/database_configurations/url_config.rb +12 -12
- data/lib/active_record/dynamic_matchers.rb +1 -1
- data/lib/active_record/enum.rb +6 -0
- data/lib/active_record/errors.rb +1 -1
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/insert_all.rb +180 -0
- data/lib/active_record/integration.rb +13 -1
- data/lib/active_record/internal_metadata.rb +5 -1
- data/lib/active_record/locking/optimistic.rb +3 -4
- data/lib/active_record/log_subscriber.rb +1 -1
- data/lib/active_record/migration.rb +25 -18
- data/lib/active_record/migration/command_recorder.rb +28 -14
- data/lib/active_record/migration/compatibility.rb +10 -0
- data/lib/active_record/persistence.rb +206 -13
- data/lib/active_record/querying.rb +17 -12
- data/lib/active_record/railties/databases.rake +68 -6
- data/lib/active_record/reflection.rb +2 -2
- data/lib/active_record/relation.rb +98 -20
- data/lib/active_record/relation/calculations.rb +39 -39
- data/lib/active_record/relation/delegation.rb +22 -30
- data/lib/active_record/relation/finder_methods.rb +3 -9
- data/lib/active_record/relation/merger.rb +7 -16
- data/lib/active_record/relation/query_methods.rb +153 -38
- data/lib/active_record/relation/where_clause.rb +9 -5
- data/lib/active_record/sanitization.rb +3 -2
- data/lib/active_record/schema_dumper.rb +5 -0
- data/lib/active_record/schema_migration.rb +1 -1
- data/lib/active_record/scoping/default.rb +6 -7
- data/lib/active_record/scoping/named.rb +1 -1
- data/lib/active_record/statement_cache.rb +2 -2
- data/lib/active_record/store.rb +48 -0
- data/lib/active_record/table_metadata.rb +3 -3
- data/lib/active_record/tasks/database_tasks.rb +36 -1
- data/lib/active_record/touch_later.rb +2 -2
- data/lib/active_record/transactions.rb +52 -41
- data/lib/active_record/validations/uniqueness.rb +3 -5
- data/lib/arel/insert_manager.rb +3 -3
- data/lib/arel/nodes.rb +2 -1
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/select_core.rb +16 -12
- data/lib/arel/nodes/unary.rb +1 -0
- data/lib/arel/nodes/values_list.rb +2 -17
- data/lib/arel/select_manager.rb +10 -10
- data/lib/arel/visitors/depth_first.rb +6 -1
- data/lib/arel/visitors/dot.rb +7 -2
- data/lib/arel/visitors/ibm_db.rb +13 -0
- data/lib/arel/visitors/informix.rb +6 -0
- data/lib/arel/visitors/mssql.rb +15 -1
- data/lib/arel/visitors/oracle12.rb +4 -5
- data/lib/arel/visitors/postgresql.rb +4 -10
- data/lib/arel/visitors/to_sql.rb +87 -108
- data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -1
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
- metadata +12 -11
- data/lib/active_record/collection_cache_key.rb +0 -53
- data/lib/arel/nodes/values.rb +0 -16
@@ -74,11 +74,11 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
74
74
|
|
75
75
|
def self.add_touch_callbacks(model, reflection)
|
76
76
|
foreign_key = reflection.foreign_key
|
77
|
-
|
77
|
+
name = reflection.name
|
78
78
|
touch = reflection.options[:touch]
|
79
79
|
|
80
80
|
callback = lambda { |changes_method| lambda { |record|
|
81
|
-
BelongsTo.touch_record(record, record.send(changes_method), foreign_key,
|
81
|
+
BelongsTo.touch_record(record, record.send(changes_method), foreign_key, name, touch, belongs_to_touch_method)
|
82
82
|
}}
|
83
83
|
|
84
84
|
if reflection.counter_cache_column
|
@@ -123,5 +123,8 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
123
123
|
model.validates_presence_of reflection.name, message: :required
|
124
124
|
end
|
125
125
|
end
|
126
|
+
|
127
|
+
private_class_method :macro, :valid_options, :valid_dependent_options, :define_callbacks, :define_validations,
|
128
|
+
:add_counter_cache_callbacks, :add_touch_callbacks, :add_default_callbacks, :add_destroy_callbacks
|
126
129
|
end
|
127
130
|
end
|
@@ -20,10 +20,10 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
20
20
|
}
|
21
21
|
end
|
22
22
|
|
23
|
-
def self.define_extensions(model, name)
|
23
|
+
def self.define_extensions(model, name, &block)
|
24
24
|
if block_given?
|
25
25
|
extension_module_name = "#{model.name.demodulize}#{name.to_s.camelize}AssociationExtension"
|
26
|
-
extension = Module.new(&
|
26
|
+
extension = Module.new(&block)
|
27
27
|
model.module_parent.const_set(extension_module_name, extension)
|
28
28
|
end
|
29
29
|
end
|
@@ -67,16 +67,6 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
67
67
|
CODE
|
68
68
|
end
|
69
69
|
|
70
|
-
|
71
|
-
if scope
|
72
|
-
if scope.arity > 0
|
73
|
-
proc { |owner| instance_exec(owner, &scope).extending(mod) }
|
74
|
-
else
|
75
|
-
proc { instance_exec(&scope).extending(mod) }
|
76
|
-
end
|
77
|
-
else
|
78
|
-
proc { extending(mod) }
|
79
|
-
end
|
80
|
-
end
|
70
|
+
private_class_method :valid_options, :define_callback, :define_extensions, :define_readers, :define_writers
|
81
71
|
end
|
82
72
|
end
|
@@ -13,5 +13,7 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
13
13
|
def self.valid_dependent_options
|
14
14
|
[:destroy, :delete_all, :nullify, :restrict_with_error, :restrict_with_exception]
|
15
15
|
end
|
16
|
+
|
17
|
+
private_class_method :macro, :valid_options, :valid_dependent_options
|
16
18
|
end
|
17
19
|
end
|
@@ -7,7 +7,7 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def self.valid_options(options)
|
10
|
-
valid = super + [:as]
|
10
|
+
valid = super + [:as, :touch]
|
11
11
|
valid += [:through, :source, :source_type] if options[:through]
|
12
12
|
valid
|
13
13
|
end
|
@@ -16,6 +16,11 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
16
16
|
[:destroy, :delete, :nullify, :restrict_with_error, :restrict_with_exception]
|
17
17
|
end
|
18
18
|
|
19
|
+
def self.define_callbacks(model, reflection)
|
20
|
+
super
|
21
|
+
add_touch_callbacks(model, reflection) if reflection.options[:touch]
|
22
|
+
end
|
23
|
+
|
19
24
|
def self.add_destroy_callbacks(model, reflection)
|
20
25
|
super unless reflection.options[:through]
|
21
26
|
end
|
@@ -26,5 +31,34 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
26
31
|
model.validates_presence_of reflection.name, message: :required
|
27
32
|
end
|
28
33
|
end
|
34
|
+
|
35
|
+
def self.touch_record(o, name, touch)
|
36
|
+
record = o.send name
|
37
|
+
|
38
|
+
return unless record && record.persisted?
|
39
|
+
|
40
|
+
if touch != true
|
41
|
+
record.touch(touch)
|
42
|
+
else
|
43
|
+
record.touch
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.add_touch_callbacks(model, reflection)
|
48
|
+
name = reflection.name
|
49
|
+
touch = reflection.options[:touch]
|
50
|
+
|
51
|
+
callback = lambda { |record|
|
52
|
+
HasOne.touch_record(record, name, touch)
|
53
|
+
}
|
54
|
+
|
55
|
+
model.after_create callback, if: :saved_changes?
|
56
|
+
model.after_update callback, if: :saved_changes?
|
57
|
+
model.after_destroy callback
|
58
|
+
model.after_touch callback
|
59
|
+
end
|
60
|
+
|
61
|
+
private_class_method :macro, :valid_options, :valid_dependent_options, :add_destroy_callbacks,
|
62
|
+
:define_callbacks, :define_validations, :add_touch_callbacks
|
29
63
|
end
|
30
64
|
end
|
@@ -1002,7 +1002,7 @@ module ActiveRecord
|
|
1002
1002
|
end
|
1003
1003
|
|
1004
1004
|
# Adds one or more +records+ to the collection by setting their foreign keys
|
1005
|
-
# to the association's primary key. Since
|
1005
|
+
# to the association's primary key. Since <tt><<</tt> flattens its argument list and
|
1006
1006
|
# inserts each record, +push+ and +concat+ behave identically. Returns +self+
|
1007
1007
|
# so several appends may be chained together.
|
1008
1008
|
#
|
@@ -57,21 +57,14 @@ module ActiveRecord
|
|
57
57
|
@through_records[record.object_id] ||= begin
|
58
58
|
ensure_mutable
|
59
59
|
|
60
|
-
|
61
|
-
|
60
|
+
attributes = through_scope_attributes
|
61
|
+
attributes[source_reflection.name] = record
|
62
|
+
attributes[source_reflection.foreign_type] = options[:source_type] if options[:source_type]
|
62
63
|
|
63
|
-
|
64
|
-
through_record.send("#{source_reflection.foreign_type}=", options[:source_type])
|
65
|
-
end
|
66
|
-
|
67
|
-
through_record
|
64
|
+
through_association.build(attributes)
|
68
65
|
end
|
69
66
|
end
|
70
67
|
|
71
|
-
def options_for_through_record
|
72
|
-
[through_scope_attributes]
|
73
|
-
end
|
74
|
-
|
75
68
|
def through_scope_attributes
|
76
69
|
scope.where_values_hash(through_association.reflection.name.to_s).
|
77
70
|
except!(through_association.reflection.foreign_key,
|
@@ -143,16 +143,13 @@ module ActiveRecord
|
|
143
143
|
|
144
144
|
def preloaders_for_reflection(reflection, records, scope)
|
145
145
|
records.group_by { |record| record.association(reflection.name).klass }.map do |rhs_klass, rs|
|
146
|
-
|
147
|
-
loader.run self
|
148
|
-
loader
|
146
|
+
preloader_for(reflection, rs).new(rhs_klass, rs, reflection, scope).run
|
149
147
|
end
|
150
148
|
end
|
151
149
|
|
152
150
|
def grouped_records(association, records, polymorphic_parent)
|
153
151
|
h = {}
|
154
152
|
records.each do |record|
|
155
|
-
next unless record
|
156
153
|
reflection = record.class._reflect_on_association(association)
|
157
154
|
next if polymorphic_parent && !reflection || !record.association(association).klass
|
158
155
|
(h[reflection] ||= []) << record
|
@@ -166,10 +163,18 @@ module ActiveRecord
|
|
166
163
|
@reflection = reflection
|
167
164
|
end
|
168
165
|
|
169
|
-
def run
|
166
|
+
def run
|
167
|
+
self
|
168
|
+
end
|
170
169
|
|
171
170
|
def preloaded_records
|
172
|
-
|
171
|
+
@preloaded_records ||= records_by_owner.flat_map(&:last)
|
172
|
+
end
|
173
|
+
|
174
|
+
def records_by_owner
|
175
|
+
@records_by_owner ||= owners.each_with_object({}) do |owner, result|
|
176
|
+
result[owner] = Array(owner.association(reflection.name).target)
|
177
|
+
end
|
173
178
|
end
|
174
179
|
|
175
180
|
private
|
@@ -4,29 +4,41 @@ module ActiveRecord
|
|
4
4
|
module Associations
|
5
5
|
class Preloader
|
6
6
|
class Association #:nodoc:
|
7
|
-
attr_reader :preloaded_records
|
8
|
-
|
9
7
|
def initialize(klass, owners, reflection, preload_scope)
|
10
8
|
@klass = klass
|
11
9
|
@owners = owners
|
12
10
|
@reflection = reflection
|
13
11
|
@preload_scope = preload_scope
|
14
12
|
@model = owners.first && owners.first.class
|
15
|
-
@preloaded_records = []
|
16
13
|
end
|
17
14
|
|
18
|
-
def run
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
15
|
+
def run
|
16
|
+
if !preload_scope || preload_scope.empty_scope?
|
17
|
+
owners.each do |owner|
|
18
|
+
associate_records_to_owner(owner, records_by_owner[owner] || [])
|
19
|
+
end
|
20
|
+
else
|
21
|
+
# Custom preload scope is used and
|
22
|
+
# the association can not be marked as loaded
|
23
|
+
# Loading into a Hash instead
|
24
|
+
records_by_owner
|
23
25
|
end
|
26
|
+
self
|
27
|
+
end
|
24
28
|
|
25
|
-
|
26
|
-
|
29
|
+
def records_by_owner
|
30
|
+
@records_by_owner ||= preloaded_records.each_with_object({}) do |record, result|
|
31
|
+
owners_by_key[convert_key(record[association_key_name])].each do |owner|
|
32
|
+
(result[owner] ||= []) << record
|
33
|
+
end
|
27
34
|
end
|
28
35
|
end
|
29
36
|
|
37
|
+
def preloaded_records
|
38
|
+
return @preloaded_records if defined?(@preloaded_records)
|
39
|
+
@preloaded_records = owner_keys.empty? ? [] : records_for(owner_keys)
|
40
|
+
end
|
41
|
+
|
30
42
|
private
|
31
43
|
attr_reader :owners, :reflection, :preload_scope, :model, :klass
|
32
44
|
|
@@ -54,13 +66,10 @@ module ActiveRecord
|
|
54
66
|
end
|
55
67
|
|
56
68
|
def owners_by_key
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
h[key] = owner if key
|
61
|
-
end
|
69
|
+
@owners_by_key ||= owners.each_with_object({}) do |owner, result|
|
70
|
+
key = convert_key(owner[owner_key_name])
|
71
|
+
(result[key] ||= []) << owner if key
|
62
72
|
end
|
63
|
-
@owners_by_key
|
64
73
|
end
|
65
74
|
|
66
75
|
def key_conversion_required?
|
@@ -87,23 +96,16 @@ module ActiveRecord
|
|
87
96
|
@model.type_for_attribute(owner_key_name).type
|
88
97
|
end
|
89
98
|
|
90
|
-
def
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
end
|
98
|
-
@preloaded_records.group_by do |record|
|
99
|
-
convert_key(record[association_key_name])
|
99
|
+
def records_for(ids)
|
100
|
+
scope.where(association_key_name => ids).load do |record|
|
101
|
+
# Processing only the first owner
|
102
|
+
# because the record is modified but not an owner
|
103
|
+
owner = owners_by_key[convert_key(record[association_key_name])].first
|
104
|
+
association = owner.association(reflection.name)
|
105
|
+
association.set_inverse_instance(record)
|
100
106
|
end
|
101
107
|
end
|
102
108
|
|
103
|
-
def records_for(ids, &block)
|
104
|
-
scope.where(association_key_name => ids).load(&block)
|
105
|
-
end
|
106
|
-
|
107
109
|
def scope
|
108
110
|
@scope ||= build_scope
|
109
111
|
end
|
@@ -4,41 +4,57 @@ module ActiveRecord
|
|
4
4
|
module Associations
|
5
5
|
class Preloader
|
6
6
|
class ThroughAssociation < Association # :nodoc:
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
7
|
+
PRELOADER = ActiveRecord::Associations::Preloader.new
|
8
|
+
|
9
|
+
def initialize(*)
|
10
|
+
super
|
11
|
+
@already_loaded = owners.first.association(through_reflection.name).loaded?
|
12
|
+
end
|
13
|
+
|
14
|
+
def preloaded_records
|
15
|
+
@preloaded_records ||= source_preloaders.flat_map(&:preloaded_records)
|
16
|
+
end
|
17
|
+
|
18
|
+
def records_by_owner
|
19
|
+
return @records_by_owner if defined?(@records_by_owner)
|
20
|
+
source_records_by_owner = source_preloaders.map(&:records_by_owner).reduce(:merge)
|
21
|
+
through_records_by_owner = through_preloaders.map(&:records_by_owner).reduce(:merge)
|
22
|
+
|
23
|
+
@records_by_owner = owners.each_with_object({}) do |owner, result|
|
24
|
+
through_records = through_records_by_owner[owner] || []
|
25
|
+
|
26
|
+
if @already_loaded
|
18
27
|
if source_type = reflection.options[:source_type]
|
19
28
|
through_records = through_records.select do |record|
|
20
29
|
record[reflection.foreign_type] == source_type
|
21
30
|
end
|
22
31
|
end
|
23
|
-
else
|
24
|
-
owner.association(through_reflection.name).reset if through_scope
|
25
|
-
end
|
26
|
-
result = through_records.flat_map do |record|
|
27
|
-
record.association(source_reflection.name).target
|
28
32
|
end
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
associate_records_to_owner(owner, result)
|
33
|
-
end
|
34
|
-
unless scope.empty_scope?
|
35
|
-
middle_records.each do |owner|
|
36
|
-
owner.association(source_reflection.name).reset
|
33
|
+
|
34
|
+
records = through_records.flat_map do |record|
|
35
|
+
source_records_by_owner[record]
|
37
36
|
end
|
37
|
+
|
38
|
+
records.compact!
|
39
|
+
records.sort_by! { |rhs| preload_index[rhs] } if scope.order_values.any?
|
40
|
+
records.uniq! if scope.distinct_value
|
41
|
+
result[owner] = records
|
38
42
|
end
|
39
43
|
end
|
40
44
|
|
41
45
|
private
|
46
|
+
def source_preloaders
|
47
|
+
@source_preloaders ||= PRELOADER.preload(middle_records, source_reflection.name, scope)
|
48
|
+
end
|
49
|
+
|
50
|
+
def middle_records
|
51
|
+
through_preloaders.flat_map(&:preloaded_records)
|
52
|
+
end
|
53
|
+
|
54
|
+
def through_preloaders
|
55
|
+
@through_preloaders ||= PRELOADER.preload(owners, through_reflection.name, through_scope)
|
56
|
+
end
|
57
|
+
|
42
58
|
def through_reflection
|
43
59
|
reflection.through_reflection
|
44
60
|
end
|
@@ -48,8 +64,8 @@ module ActiveRecord
|
|
48
64
|
end
|
49
65
|
|
50
66
|
def preload_index
|
51
|
-
@preload_index ||=
|
52
|
-
result[
|
67
|
+
@preload_index ||= preloaded_records.each_with_object({}).with_index do |(record, result), index|
|
68
|
+
result[record] = index
|
53
69
|
end
|
54
70
|
end
|
55
71
|
|
@@ -57,11 +73,15 @@ module ActiveRecord
|
|
57
73
|
scope = through_reflection.klass.unscoped
|
58
74
|
options = reflection.options
|
59
75
|
|
76
|
+
values = reflection_scope.values
|
77
|
+
if annotations = values[:annotate]
|
78
|
+
scope.annotate!(*annotations)
|
79
|
+
end
|
80
|
+
|
60
81
|
if options[:source_type]
|
61
82
|
scope.where! reflection.foreign_type => options[:source_type]
|
62
83
|
elsif !reflection_scope.where_clause.empty?
|
63
84
|
scope.where_clause = reflection_scope.where_clause
|
64
|
-
values = reflection_scope.values
|
65
85
|
|
66
86
|
if includes = values[:includes]
|
67
87
|
scope.includes!(source_reflection.name => includes)
|
@@ -88,7 +108,7 @@ module ActiveRecord
|
|
88
108
|
end
|
89
109
|
end
|
90
110
|
|
91
|
-
scope
|
111
|
+
scope
|
92
112
|
end
|
93
113
|
end
|
94
114
|
end
|
@@ -35,7 +35,8 @@ module ActiveRecord
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def initialize_generated_modules # :nodoc:
|
38
|
-
@generated_attribute_methods = GeneratedAttributeMethods.new
|
38
|
+
@generated_attribute_methods = const_set(:GeneratedAttributeMethods, GeneratedAttributeMethods.new)
|
39
|
+
private_constant :GeneratedAttributeMethods
|
39
40
|
@attribute_methods_generated = false
|
40
41
|
include @generated_attribute_methods
|
41
42
|
|
@@ -196,7 +197,7 @@ module ActiveRecord
|
|
196
197
|
"Dangerous query method (method whose arguments are used as raw " \
|
197
198
|
"SQL) called with non-attribute argument(s): " \
|
198
199
|
"#{unexpected.map(&:inspect).join(", ")}. Non-attribute " \
|
199
|
-
"arguments will be disallowed in Rails 6.
|
200
|
+
"arguments will be disallowed in Rails 6.1. This method should " \
|
200
201
|
"not be called with user-provided values, such as request " \
|
201
202
|
"parameters or model attributes. Known-safe values can be passed " \
|
202
203
|
"by wrapping them in Arel.sql()."
|
@@ -464,7 +465,7 @@ module ActiveRecord
|
|
464
465
|
end
|
465
466
|
|
466
467
|
def pk_attribute?(name)
|
467
|
-
name ==
|
468
|
+
name == @primary_key
|
468
469
|
end
|
469
470
|
end
|
470
471
|
end
|
@@ -46,6 +46,7 @@ module ActiveRecord
|
|
46
46
|
# task.read_attribute_before_type_cast('completed_on') # => "2012-10-21"
|
47
47
|
# task.read_attribute_before_type_cast(:completed_on) # => "2012-10-21"
|
48
48
|
def read_attribute_before_type_cast(attr_name)
|
49
|
+
sync_with_transaction_state if @transaction_state&.finalized?
|
49
50
|
@attributes[attr_name.to_s].value_before_type_cast
|
50
51
|
end
|
51
52
|
|
@@ -60,17 +61,19 @@ module ActiveRecord
|
|
60
61
|
# task.attributes_before_type_cast
|
61
62
|
# # => {"id"=>nil, "title"=>nil, "is_done"=>true, "completed_on"=>"2012-10-21", "created_at"=>nil, "updated_at"=>nil}
|
62
63
|
def attributes_before_type_cast
|
64
|
+
sync_with_transaction_state if @transaction_state&.finalized?
|
63
65
|
@attributes.values_before_type_cast
|
64
66
|
end
|
65
67
|
|
66
68
|
private
|
67
69
|
|
68
|
-
#
|
70
|
+
# Dispatch target for <tt>*_before_type_cast</tt> attribute methods.
|
69
71
|
def attribute_before_type_cast(attribute_name)
|
70
72
|
read_attribute_before_type_cast(attribute_name)
|
71
73
|
end
|
72
74
|
|
73
75
|
def attribute_came_from_user?(attribute_name)
|
76
|
+
sync_with_transaction_state if @transaction_state&.finalized?
|
74
77
|
@attributes[attribute_name].came_from_user?
|
75
78
|
end
|
76
79
|
end
|