activerecord 7.2.1 → 8.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +188 -786
- data/README.rdoc +1 -1
- data/lib/active_record/associations/association.rb +25 -5
- data/lib/active_record/associations/builder/association.rb +7 -6
- data/lib/active_record/associations/collection_association.rb +10 -8
- data/lib/active_record/associations/disable_joins_association_scope.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +3 -2
- data/lib/active_record/associations/join_dependency/join_association.rb +3 -2
- data/lib/active_record/associations/join_dependency.rb +4 -4
- data/lib/active_record/associations/preloader/association.rb +2 -2
- data/lib/active_record/associations/singular_association.rb +8 -3
- data/lib/active_record/associations.rb +34 -4
- data/lib/active_record/asynchronous_queries_tracker.rb +28 -24
- data/lib/active_record/attribute_assignment.rb +9 -1
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -0
- data/lib/active_record/attributes.rb +1 -2
- data/lib/active_record/autosave_association.rb +69 -27
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +16 -10
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +90 -43
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +12 -4
- data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +26 -5
- data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -5
- data/lib/active_record/connection_adapters/abstract_adapter.rb +24 -25
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +20 -38
- data/lib/active_record/connection_adapters/mysql/quoting.rb +0 -8
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +2 -8
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +43 -45
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +42 -98
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -8
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -42
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +10 -0
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +50 -6
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +38 -90
- data/lib/active_record/connection_adapters/schema_cache.rb +1 -3
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +76 -100
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +0 -6
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +13 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +8 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +55 -12
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +37 -67
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +0 -17
- data/lib/active_record/connection_handling.rb +22 -0
- data/lib/active_record/core.rb +14 -7
- data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -1
- data/lib/active_record/encryption/config.rb +3 -1
- data/lib/active_record/encryption/encryptable_record.rb +4 -4
- data/lib/active_record/encryption/encrypted_attribute_type.rb +10 -1
- data/lib/active_record/encryption/encryptor.rb +15 -8
- data/lib/active_record/encryption/extended_deterministic_queries.rb +4 -2
- data/lib/active_record/encryption/key_provider.rb +1 -1
- data/lib/active_record/encryption/scheme.rb +8 -1
- data/lib/active_record/encryption.rb +2 -0
- data/lib/active_record/enum.rb +7 -10
- data/lib/active_record/errors.rb +13 -5
- data/lib/active_record/fixtures.rb +0 -1
- data/lib/active_record/future_result.rb +14 -10
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/insert_all.rb +1 -1
- data/lib/active_record/migration/command_recorder.rb +22 -5
- data/lib/active_record/migration/compatibility.rb +5 -2
- data/lib/active_record/migration.rb +35 -33
- data/lib/active_record/model_schema.rb +2 -3
- data/lib/active_record/nested_attributes.rb +11 -2
- data/lib/active_record/persistence.rb +128 -130
- data/lib/active_record/query_logs.rb +97 -39
- data/lib/active_record/query_logs_formatter.rb +17 -28
- data/lib/active_record/querying.rb +6 -6
- data/lib/active_record/railtie.rb +8 -14
- data/lib/active_record/reflection.rb +9 -4
- data/lib/active_record/relation/batches/batch_enumerator.rb +4 -3
- data/lib/active_record/relation/batches.rb +132 -72
- data/lib/active_record/relation/calculations.rb +24 -19
- data/lib/active_record/relation/delegation.rb +25 -14
- data/lib/active_record/relation/finder_methods.rb +18 -18
- data/lib/active_record/relation/merger.rb +8 -8
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -1
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +4 -3
- data/lib/active_record/relation/predicate_builder.rb +6 -1
- data/lib/active_record/relation/query_methods.rb +58 -37
- data/lib/active_record/relation/record_fetch_warning.rb +2 -2
- data/lib/active_record/relation/spawn_methods.rb +1 -1
- data/lib/active_record/relation.rb +72 -61
- data/lib/active_record/result.rb +68 -7
- data/lib/active_record/sanitization.rb +7 -6
- data/lib/active_record/schema_dumper.rb +5 -0
- data/lib/active_record/schema_migration.rb +2 -1
- data/lib/active_record/scoping/named.rb +5 -2
- data/lib/active_record/statement_cache.rb +12 -12
- data/lib/active_record/store.rb +7 -3
- data/lib/active_record/tasks/database_tasks.rb +36 -16
- data/lib/active_record/tasks/mysql_database_tasks.rb +0 -2
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -2
- data/lib/active_record/test_fixtures.rb +12 -0
- data/lib/active_record/token_for.rb +1 -1
- data/lib/active_record/validations/uniqueness.rb +9 -8
- data/lib/active_record.rb +15 -0
- data/lib/arel/collectors/bind.rb +1 -1
- metadata +14 -14
@@ -145,10 +145,10 @@ module ActiveRecord
|
|
145
145
|
|
146
146
|
if found.nil?
|
147
147
|
raise_record_not_found_exception!
|
148
|
-
elsif undesired.
|
149
|
-
raise ActiveRecord::SoleRecordExceeded.new(self)
|
150
|
-
else
|
148
|
+
elsif undesired.nil?
|
151
149
|
found
|
150
|
+
else
|
151
|
+
raise ActiveRecord::SoleRecordExceeded.new(model)
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
@@ -376,7 +376,7 @@ module ActiveRecord
|
|
376
376
|
|
377
377
|
skip_query_cache_if_necessary do
|
378
378
|
with_connection do |c|
|
379
|
-
c.select_rows(relation.arel, "#{name} Exists?").size == 1
|
379
|
+
c.select_rows(relation.arel, "#{model.name} Exists?").size == 1
|
380
380
|
end
|
381
381
|
end
|
382
382
|
end
|
@@ -389,7 +389,7 @@ module ActiveRecord
|
|
389
389
|
def include?(record)
|
390
390
|
# The existing implementation relies on receiving an Active Record instance as the input parameter named record.
|
391
391
|
# Any non-Active Record object passed to this implementation is guaranteed to return `false`.
|
392
|
-
return false unless record.is_a?(
|
392
|
+
return false unless record.is_a?(model)
|
393
393
|
|
394
394
|
if loaded? || offset_value || limit_value || having_clause.any?
|
395
395
|
records.include?(record)
|
@@ -415,9 +415,9 @@ module ActiveRecord
|
|
415
415
|
# the expected number of results should be provided in the +expected_size+
|
416
416
|
# argument.
|
417
417
|
def raise_record_not_found_exception!(ids = nil, result_size = nil, expected_size = nil, key = primary_key, not_found_ids = nil) # :nodoc:
|
418
|
-
conditions = " [#{arel.where_sql(
|
418
|
+
conditions = " [#{arel.where_sql(model)}]" unless where_clause.empty?
|
419
419
|
|
420
|
-
name =
|
420
|
+
name = model.name
|
421
421
|
|
422
422
|
if ids.nil?
|
423
423
|
error = +"Couldn't find #{name}"
|
@@ -471,7 +471,7 @@ module ActiveRecord
|
|
471
471
|
)
|
472
472
|
)
|
473
473
|
relation = skip_query_cache_if_necessary do
|
474
|
-
|
474
|
+
model.with_connection do |c|
|
475
475
|
c.distinct_relation_for_primary_key(relation)
|
476
476
|
end
|
477
477
|
end
|
@@ -489,9 +489,9 @@ module ActiveRecord
|
|
489
489
|
end
|
490
490
|
|
491
491
|
def find_with_ids(*ids)
|
492
|
-
raise UnknownPrimaryKey.new(
|
492
|
+
raise UnknownPrimaryKey.new(model) if primary_key.nil?
|
493
493
|
|
494
|
-
expects_array = if
|
494
|
+
expects_array = if model.composite_primary_key?
|
495
495
|
ids.first.first.is_a?(Array)
|
496
496
|
else
|
497
497
|
ids.first.is_a?(Array)
|
@@ -503,7 +503,7 @@ module ActiveRecord
|
|
503
503
|
|
504
504
|
ids = ids.compact.uniq
|
505
505
|
|
506
|
-
model_name =
|
506
|
+
model_name = model.name
|
507
507
|
|
508
508
|
case ids.size
|
509
509
|
when 0
|
@@ -525,7 +525,7 @@ module ActiveRecord
|
|
525
525
|
MSG
|
526
526
|
end
|
527
527
|
|
528
|
-
relation = if
|
528
|
+
relation = if model.composite_primary_key?
|
529
529
|
where(primary_key.zip(id).to_h)
|
530
530
|
else
|
531
531
|
where(primary_key => id)
|
@@ -573,7 +573,7 @@ module ActiveRecord
|
|
573
573
|
result = relation.records
|
574
574
|
|
575
575
|
if result.size == ids.size
|
576
|
-
result.in_order_of(:id, ids.map { |id|
|
576
|
+
result.in_order_of(:id, ids.map { |id| model.type_for_attribute(primary_key).cast(id) })
|
577
577
|
else
|
578
578
|
raise_record_not_found_exception!(ids, result.size, ids.size)
|
579
579
|
end
|
@@ -638,7 +638,7 @@ module ActiveRecord
|
|
638
638
|
end
|
639
639
|
|
640
640
|
def ordered_relation
|
641
|
-
if order_values.empty? && (implicit_order_column || !query_constraints_list.nil? || primary_key)
|
641
|
+
if order_values.empty? && (model.implicit_order_column || !model.query_constraints_list.nil? || primary_key)
|
642
642
|
order(_order_columns.map { |column| table[column].asc })
|
643
643
|
else
|
644
644
|
self
|
@@ -648,11 +648,11 @@ module ActiveRecord
|
|
648
648
|
def _order_columns
|
649
649
|
oc = []
|
650
650
|
|
651
|
-
oc << implicit_order_column if implicit_order_column
|
652
|
-
oc << query_constraints_list if query_constraints_list
|
651
|
+
oc << model.implicit_order_column if model.implicit_order_column
|
652
|
+
oc << model.query_constraints_list if model.query_constraints_list
|
653
653
|
|
654
|
-
if primary_key && query_constraints_list.nil?
|
655
|
-
oc << primary_key
|
654
|
+
if model.primary_key && model.query_constraints_list.nil?
|
655
|
+
oc << model.primary_key
|
656
656
|
end
|
657
657
|
|
658
658
|
oc.flatten.uniq.compact
|
@@ -24,7 +24,7 @@ module ActiveRecord
|
|
24
24
|
# the values.
|
25
25
|
def other
|
26
26
|
other = Relation.create(
|
27
|
-
relation.
|
27
|
+
relation.model,
|
28
28
|
table: relation.table,
|
29
29
|
predicate_builder: relation.predicate_builder
|
30
30
|
)
|
@@ -84,7 +84,7 @@ module ActiveRecord
|
|
84
84
|
def merge_select_values
|
85
85
|
return if other.select_values.empty?
|
86
86
|
|
87
|
-
if other.
|
87
|
+
if other.model == relation.model
|
88
88
|
relation.select_values |= other.select_values
|
89
89
|
else
|
90
90
|
relation.select_values |= other.instance_eval do
|
@@ -96,12 +96,12 @@ module ActiveRecord
|
|
96
96
|
def merge_preloads
|
97
97
|
return if other.preload_values.empty? && other.includes_values.empty?
|
98
98
|
|
99
|
-
if other.
|
99
|
+
if other.model == relation.model
|
100
100
|
relation.preload_values |= other.preload_values unless other.preload_values.empty?
|
101
101
|
relation.includes_values |= other.includes_values unless other.includes_values.empty?
|
102
102
|
else
|
103
|
-
reflection = relation.
|
104
|
-
r.class_name == other.
|
103
|
+
reflection = relation.model.reflect_on_all_associations.find do |r|
|
104
|
+
r.class_name == other.model.name
|
105
105
|
end || return
|
106
106
|
|
107
107
|
unless other.preload_values.empty?
|
@@ -117,7 +117,7 @@ module ActiveRecord
|
|
117
117
|
def merge_joins
|
118
118
|
return if other.joins_values.empty?
|
119
119
|
|
120
|
-
if other.
|
120
|
+
if other.model == relation.model
|
121
121
|
relation.joins_values |= other.joins_values
|
122
122
|
else
|
123
123
|
associations, others = other.joins_values.partition do |join|
|
@@ -136,7 +136,7 @@ module ActiveRecord
|
|
136
136
|
def merge_outer_joins
|
137
137
|
return if other.left_outer_joins_values.empty?
|
138
138
|
|
139
|
-
if other.
|
139
|
+
if other.model == relation.model
|
140
140
|
relation.left_outer_joins_values |= other.left_outer_joins_values
|
141
141
|
else
|
142
142
|
associations, others = other.left_outer_joins_values.partition do |join|
|
@@ -185,7 +185,7 @@ module ActiveRecord
|
|
185
185
|
|
186
186
|
def replace_from_clause?
|
187
187
|
relation.from_clause.empty? && !other.from_clause.empty? &&
|
188
|
-
relation.
|
188
|
+
relation.model.base_class == other.model.base_class
|
189
189
|
end
|
190
190
|
end
|
191
191
|
end
|
@@ -9,10 +9,11 @@ module ActiveRecord
|
|
9
9
|
end
|
10
10
|
|
11
11
|
if value.select_values.empty?
|
12
|
-
|
13
|
-
|
12
|
+
model = value.model
|
13
|
+
if model.composite_primary_key?
|
14
|
+
raise ArgumentError, "Cannot map composite primary key #{model.primary_key} to #{attribute.name}"
|
14
15
|
else
|
15
|
-
value = value.select(value.table[
|
16
|
+
value = value.select(value.table[model.primary_key])
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
@@ -77,6 +77,11 @@ module ActiveRecord
|
|
77
77
|
return ["1=0"] if attributes.empty?
|
78
78
|
|
79
79
|
attributes.flat_map do |key, value|
|
80
|
+
if key.is_a?(Array) && key.size == 1
|
81
|
+
key = key.first
|
82
|
+
value = value.flatten
|
83
|
+
end
|
84
|
+
|
80
85
|
if key.is_a?(Array)
|
81
86
|
queries = Array(value).map do |ids_set|
|
82
87
|
raise ArgumentError, "Expected corresponding value for #{key} to be an Array" unless ids_set.is_a?(Array)
|
@@ -142,7 +147,7 @@ module ActiveRecord
|
|
142
147
|
queries.first
|
143
148
|
else
|
144
149
|
queries.map! { |query| query.reduce(&:and) }
|
145
|
-
queries =
|
150
|
+
queries = Arel::Nodes::Or.new(queries)
|
146
151
|
Arel::Nodes::Grouping.new(queries)
|
147
152
|
end
|
148
153
|
end
|
@@ -92,10 +92,11 @@ module ActiveRecord
|
|
92
92
|
@scope.joins!(association)
|
93
93
|
end
|
94
94
|
|
95
|
+
association_conditions = Array(reflection.association_primary_key).index_with(nil)
|
95
96
|
if reflection.options[:class_name]
|
96
|
-
self.not(association =>
|
97
|
+
self.not(association => association_conditions)
|
97
98
|
else
|
98
|
-
self.not(reflection.table_name =>
|
99
|
+
self.not(reflection.table_name => association_conditions)
|
99
100
|
end
|
100
101
|
end
|
101
102
|
|
@@ -124,10 +125,11 @@ module ActiveRecord
|
|
124
125
|
associations.each do |association|
|
125
126
|
reflection = scope_association_reflection(association)
|
126
127
|
@scope.left_outer_joins!(association)
|
128
|
+
association_conditions = Array(reflection.association_primary_key).index_with(nil)
|
127
129
|
if reflection.options[:class_name]
|
128
|
-
@scope.where!(association =>
|
130
|
+
@scope.where!(association => association_conditions)
|
129
131
|
else
|
130
|
-
@scope.where!(reflection.table_name =>
|
132
|
+
@scope.where!(reflection.table_name => association_conditions)
|
131
133
|
end
|
132
134
|
end
|
133
135
|
|
@@ -136,9 +138,10 @@ module ActiveRecord
|
|
136
138
|
|
137
139
|
private
|
138
140
|
def scope_association_reflection(association)
|
139
|
-
|
141
|
+
model = @scope.model
|
142
|
+
reflection = model._reflect_on_association(association)
|
140
143
|
unless reflection
|
141
|
-
raise ArgumentError.new("An association named `:#{association}` does not exist on the model `#{
|
144
|
+
raise ArgumentError.new("An association named `:#{association}` does not exist on the model `#{model.name}`.")
|
142
145
|
end
|
143
146
|
reflection
|
144
147
|
end
|
@@ -254,6 +257,10 @@ module ActiveRecord
|
|
254
257
|
self
|
255
258
|
end
|
256
259
|
|
260
|
+
def all # :nodoc:
|
261
|
+
spawn
|
262
|
+
end
|
263
|
+
|
257
264
|
# Specify associations +args+ to be eager loaded using a <tt>LEFT OUTER JOIN</tt>.
|
258
265
|
# Performs a single query joining all specified associations. For example:
|
259
266
|
#
|
@@ -696,26 +703,39 @@ module ActiveRecord
|
|
696
703
|
# # WHEN "conversations"."status" = 0 THEN 3
|
697
704
|
# # END ASC
|
698
705
|
#
|
699
|
-
|
700
|
-
|
706
|
+
# +filter+ can be set to +false+ to include all results instead of only the ones specified in +values+.
|
707
|
+
#
|
708
|
+
# Conversation.in_order_of(:status, [:archived, :active], filter: false)
|
709
|
+
# # SELECT "conversations".* FROM "conversations"
|
710
|
+
# # ORDER BY CASE
|
711
|
+
# # WHEN "conversations"."status" = 1 THEN 1
|
712
|
+
# # WHEN "conversations"."status" = 0 THEN 2
|
713
|
+
# # ELSE 3
|
714
|
+
# # END ASC
|
715
|
+
def in_order_of(column, values, filter: true)
|
716
|
+
model.disallow_raw_sql!([column], permit: model.adapter_class.column_name_with_order_matcher)
|
701
717
|
return spawn.none! if values.empty?
|
702
718
|
|
703
719
|
references = column_references([column])
|
704
720
|
self.references_values |= references unless references.empty?
|
705
721
|
|
706
|
-
values = values.map { |value| type_caster.type_cast_for_database(column, value) }
|
722
|
+
values = values.map { |value| model.type_caster.type_cast_for_database(column, value) }
|
707
723
|
arel_column = column.is_a?(Arel::Nodes::SqlLiteral) ? column : order_column(column.to_s)
|
708
724
|
|
709
|
-
|
710
|
-
if values.include?(nil)
|
711
|
-
arel_column.in(values.compact).or(arel_column.eq(nil))
|
712
|
-
else
|
713
|
-
arel_column.in(values)
|
714
|
-
end
|
725
|
+
scope = spawn.order!(build_case_for_value_position(arel_column, values, filter: filter))
|
715
726
|
|
716
|
-
|
717
|
-
|
718
|
-
|
727
|
+
if filter
|
728
|
+
where_clause =
|
729
|
+
if values.include?(nil)
|
730
|
+
arel_column.in(values.compact).or(arel_column.eq(nil))
|
731
|
+
else
|
732
|
+
arel_column.in(values)
|
733
|
+
end
|
734
|
+
|
735
|
+
scope = scope.where!(where_clause)
|
736
|
+
end
|
737
|
+
|
738
|
+
scope
|
719
739
|
end
|
720
740
|
|
721
741
|
# Replaces any existing order defined on the relation with the specified order.
|
@@ -1554,8 +1574,8 @@ module ActiveRecord
|
|
1554
1574
|
records.flatten!(1)
|
1555
1575
|
records.compact!
|
1556
1576
|
|
1557
|
-
unless records.all?(
|
1558
|
-
raise ArgumentError, "You must only pass a single or collection of #{
|
1577
|
+
unless records.all?(model) && relations.all? { |relation| relation.model == model }
|
1578
|
+
raise ArgumentError, "You must only pass a single or collection of #{model.name} objects to ##{__callee__}."
|
1559
1579
|
end
|
1560
1580
|
|
1561
1581
|
spawn.excluding!(records + relations.flat_map(&:ids))
|
@@ -1575,7 +1595,7 @@ module ActiveRecord
|
|
1575
1595
|
|
1576
1596
|
def construct_join_dependency(associations, join_type) # :nodoc:
|
1577
1597
|
ActiveRecord::Associations::JoinDependency.new(
|
1578
|
-
|
1598
|
+
model, table, associations, join_type
|
1579
1599
|
)
|
1580
1600
|
end
|
1581
1601
|
|
@@ -1604,15 +1624,15 @@ module ActiveRecord
|
|
1604
1624
|
elsif opts.include?("?")
|
1605
1625
|
parts = [build_bound_sql_literal(opts, rest)]
|
1606
1626
|
else
|
1607
|
-
parts = [
|
1627
|
+
parts = [model.sanitize_sql(rest.empty? ? opts : [opts, *rest])]
|
1608
1628
|
end
|
1609
1629
|
when Hash
|
1610
1630
|
opts = opts.transform_keys do |key|
|
1611
1631
|
if key.is_a?(Array)
|
1612
|
-
key.map { |k|
|
1632
|
+
key.map { |k| model.attribute_aliases[k.to_s] || k.to_s }
|
1613
1633
|
else
|
1614
1634
|
key = key.to_s
|
1615
|
-
|
1635
|
+
model.attribute_aliases[key] || key
|
1616
1636
|
end
|
1617
1637
|
end
|
1618
1638
|
references = PredicateBuilder.references(opts)
|
@@ -1808,7 +1828,7 @@ module ActiveRecord
|
|
1808
1828
|
|
1809
1829
|
joins = joins_values.dup
|
1810
1830
|
if joins.last.is_a?(ActiveRecord::Associations::JoinDependency)
|
1811
|
-
stashed_eager_load = joins.pop if joins.last.base_klass ==
|
1831
|
+
stashed_eager_load = joins.pop if joins.last.base_klass == model
|
1812
1832
|
end
|
1813
1833
|
|
1814
1834
|
joins.each_with_index do |join, i|
|
@@ -1865,8 +1885,8 @@ module ActiveRecord
|
|
1865
1885
|
def build_select(arel)
|
1866
1886
|
if select_values.any?
|
1867
1887
|
arel.project(*arel_columns(select_values))
|
1868
|
-
elsif
|
1869
|
-
arel.project(*
|
1888
|
+
elsif model.ignored_columns.any? || model.enumerate_columns_in_select_statements
|
1889
|
+
arel.project(*model.column_names.map { |field| table[field] })
|
1870
1890
|
else
|
1871
1891
|
arel.project(table[Arel.star])
|
1872
1892
|
end
|
@@ -1905,7 +1925,7 @@ module ActiveRecord
|
|
1905
1925
|
with_table = Arel::Table.new(name)
|
1906
1926
|
|
1907
1927
|
table.join(with_table, kind).on(
|
1908
|
-
with_table[
|
1928
|
+
with_table[model.model_name.to_s.foreign_key].eq(table[model.primary_key])
|
1909
1929
|
).join_sources.first
|
1910
1930
|
end
|
1911
1931
|
|
@@ -1914,7 +1934,7 @@ module ActiveRecord
|
|
1914
1934
|
case field
|
1915
1935
|
when Symbol
|
1916
1936
|
arel_column(field.to_s) do |attr_name|
|
1917
|
-
adapter_class.quote_table_name(attr_name)
|
1937
|
+
model.adapter_class.quote_table_name(attr_name)
|
1918
1938
|
end
|
1919
1939
|
when String
|
1920
1940
|
arel_column(field, &:itself)
|
@@ -1929,10 +1949,10 @@ module ActiveRecord
|
|
1929
1949
|
end
|
1930
1950
|
|
1931
1951
|
def arel_column(field)
|
1932
|
-
field =
|
1952
|
+
field = model.attribute_aliases[field] || field
|
1933
1953
|
from = from_clause.name || from_clause.value
|
1934
1954
|
|
1935
|
-
if
|
1955
|
+
if model.columns_hash.key?(field) && (!from || table_name_matches?(from))
|
1936
1956
|
table[field]
|
1937
1957
|
elsif field.match?(/\A\w+\.\w+\z/)
|
1938
1958
|
table, column = field.split(".")
|
@@ -1946,7 +1966,7 @@ module ActiveRecord
|
|
1946
1966
|
|
1947
1967
|
def table_name_matches?(from)
|
1948
1968
|
table_name = Regexp.escape(table.name)
|
1949
|
-
quoted_table_name = Regexp.escape(adapter_class.quote_table_name(table.name))
|
1969
|
+
quoted_table_name = Regexp.escape(model.adapter_class.quote_table_name(table.name))
|
1950
1970
|
/(?:\A|(?<!FROM)\s)(?:\b#{table_name}\b|#{quoted_table_name})(?!\.)/i.match?(from.to_s)
|
1951
1971
|
end
|
1952
1972
|
|
@@ -2017,7 +2037,7 @@ module ActiveRecord
|
|
2017
2037
|
end
|
2018
2038
|
|
2019
2039
|
def preprocess_order_args(order_args)
|
2020
|
-
|
2040
|
+
model.disallow_raw_sql!(
|
2021
2041
|
flattened_args(order_args),
|
2022
2042
|
permit: model.adapter_class.column_name_with_order_matcher
|
2023
2043
|
)
|
@@ -2055,7 +2075,7 @@ module ActiveRecord
|
|
2055
2075
|
|
2056
2076
|
def sanitize_order_arguments(order_args)
|
2057
2077
|
order_args.map! do |arg|
|
2058
|
-
|
2078
|
+
model.sanitize_sql_for_order(arg)
|
2059
2079
|
end
|
2060
2080
|
end
|
2061
2081
|
|
@@ -2093,17 +2113,18 @@ module ActiveRecord
|
|
2093
2113
|
if attr_name == "count" && !group_values.empty?
|
2094
2114
|
table[attr_name]
|
2095
2115
|
else
|
2096
|
-
Arel.sql(adapter_class.quote_table_name(attr_name), retryable: true)
|
2116
|
+
Arel.sql(model.adapter_class.quote_table_name(attr_name), retryable: true)
|
2097
2117
|
end
|
2098
2118
|
end
|
2099
2119
|
end
|
2100
2120
|
|
2101
|
-
def build_case_for_value_position(column, values)
|
2121
|
+
def build_case_for_value_position(column, values, filter: true)
|
2102
2122
|
node = Arel::Nodes::Case.new
|
2103
2123
|
values.each.with_index(1) do |value, order|
|
2104
2124
|
node.when(column.eq(value)).then(order)
|
2105
2125
|
end
|
2106
2126
|
|
2127
|
+
node = node.else(values.length + 1) unless filter
|
2107
2128
|
Arel::Nodes::Ascending.new(node)
|
2108
2129
|
end
|
2109
2130
|
|
@@ -2187,7 +2208,7 @@ module ActiveRecord
|
|
2187
2208
|
end
|
2188
2209
|
when String, Symbol
|
2189
2210
|
arel_column(key.to_s) do
|
2190
|
-
predicate_builder.resolve_arel_attribute(
|
2211
|
+
predicate_builder.resolve_arel_attribute(model.table_name, key.to_s)
|
2191
2212
|
end.as(columns_aliases.to_s)
|
2192
2213
|
end
|
2193
2214
|
end
|
@@ -20,9 +20,9 @@ module ActiveRecord
|
|
20
20
|
QueryRegistry.reset
|
21
21
|
|
22
22
|
super.tap do |records|
|
23
|
-
if logger && ActiveRecord.warn_on_records_fetched_greater_than
|
23
|
+
if model.logger && ActiveRecord.warn_on_records_fetched_greater_than
|
24
24
|
if records.length > ActiveRecord.warn_on_records_fetched_greater_than
|
25
|
-
logger.warn "Query fetched #{records.size} #{@klass} records: #{QueryRegistry.queries.join(";")}"
|
25
|
+
model.logger.warn "Query fetched #{records.size} #{@klass} records: #{QueryRegistry.queries.join(";")}"
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
@@ -7,7 +7,7 @@ require "active_record/relation/merger"
|
|
7
7
|
module ActiveRecord
|
8
8
|
module SpawnMethods
|
9
9
|
def spawn # :nodoc:
|
10
|
-
already_in_scope?(
|
10
|
+
already_in_scope?(model.scope_registry) ? model.all : clone
|
11
11
|
end
|
12
12
|
|
13
13
|
# Merges in the conditions from <tt>other</tt>, if <tt>other</tt> is an ActiveRecord::Relation.
|