activerecord 7.2.1.1 → 8.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +220 -756
- 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 +10 -3
- 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/primary_key.rb +2 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -12
- data/lib/active_record/attributes.rb +1 -2
- data/lib/active_record/autosave_association.rb +69 -27
- data/lib/active_record/callbacks.rb +1 -1
- 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 +26 -9
- 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_creation.rb +4 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +7 -2
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +34 -7
- data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -5
- data/lib/active_record/connection_adapters/abstract_adapter.rb +24 -26
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +28 -42
- 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/array.rb +1 -1
- 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/referential_integrity.rb +2 -4
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +0 -11
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -11
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +54 -14
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +45 -97
- 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 +53 -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_adapters.rb +0 -56
- data/lib/active_record/connection_handling.rb +22 -0
- data/lib/active_record/core.rb +28 -18
- 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 +54 -75
- data/lib/active_record/errors.rb +13 -5
- data/lib/active_record/fixtures.rb +0 -2
- 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/locking/optimistic.rb +1 -1
- data/lib/active_record/log_subscriber.rb +5 -11
- data/lib/active_record/marshalling.rb +4 -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 -38
- data/lib/active_record/model_schema.rb +4 -6
- data/lib/active_record/nested_attributes.rb +11 -2
- data/lib/active_record/persistence.rb +128 -130
- data/lib/active_record/query_cache.rb +0 -4
- data/lib/active_record/query_logs.rb +102 -50
- data/lib/active_record/query_logs_formatter.rb +17 -28
- data/lib/active_record/querying.rb +8 -8
- data/lib/active_record/railtie.rb +9 -38
- data/lib/active_record/railties/databases.rake +1 -1
- data/lib/active_record/reflection.rb +23 -23
- 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 +41 -40
- 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 +14 -1
- data/lib/active_record/relation/query_methods.rb +122 -71
- data/lib/active_record/relation/spawn_methods.rb +1 -1
- data/lib/active_record/relation.rb +79 -61
- data/lib/active_record/result.rb +66 -4
- 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/table_metadata.rb +1 -3
- data/lib/active_record/tasks/database_tasks.rb +40 -47
- 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/testing/query_assertions.rb +2 -2
- data/lib/active_record/token_for.rb +1 -1
- data/lib/active_record/validations/uniqueness.rb +9 -8
- data/lib/active_record.rb +15 -45
- data/lib/arel/collectors/bind.rb +1 -1
- data/lib/arel/table.rb +3 -7
- data/lib/arel/visitors/sqlite.rb +25 -0
- metadata +10 -11
- data/lib/active_record/relation/record_fetch_warning.rb +0 -52
@@ -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
|
#
|
@@ -499,7 +506,7 @@ module ActiveRecord
|
|
499
506
|
#
|
500
507
|
# Post.with_recursive(post_and_replies: [Post.where(id: 42), Post.joins('JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id')])
|
501
508
|
# # => ActiveRecord::Relation
|
502
|
-
# # WITH post_and_replies AS (
|
509
|
+
# # WITH RECURSIVE post_and_replies AS (
|
503
510
|
# # (SELECT * FROM posts WHERE id = 42)
|
504
511
|
# # UNION ALL
|
505
512
|
# # (SELECT * FROM posts JOIN posts_and_replies ON posts.in_reply_to_id = posts_and_replies.id)
|
@@ -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)
|
@@ -1636,6 +1656,22 @@ module ActiveRecord
|
|
1636
1656
|
self
|
1637
1657
|
end
|
1638
1658
|
|
1659
|
+
protected
|
1660
|
+
def arel_columns(columns)
|
1661
|
+
columns.flat_map do |field|
|
1662
|
+
case field
|
1663
|
+
when Symbol, String
|
1664
|
+
arel_column(field)
|
1665
|
+
when Proc
|
1666
|
+
field.call
|
1667
|
+
when Hash
|
1668
|
+
arel_columns_from_hash(field)
|
1669
|
+
else
|
1670
|
+
field
|
1671
|
+
end
|
1672
|
+
end
|
1673
|
+
end
|
1674
|
+
|
1639
1675
|
private
|
1640
1676
|
def async
|
1641
1677
|
spawn.async!
|
@@ -1808,7 +1844,7 @@ module ActiveRecord
|
|
1808
1844
|
|
1809
1845
|
joins = joins_values.dup
|
1810
1846
|
if joins.last.is_a?(ActiveRecord::Associations::JoinDependency)
|
1811
|
-
stashed_eager_load = joins.pop if joins.last.base_klass ==
|
1847
|
+
stashed_eager_load = joins.pop if joins.last.base_klass == model
|
1812
1848
|
end
|
1813
1849
|
|
1814
1850
|
joins.each_with_index do |join, i|
|
@@ -1865,8 +1901,8 @@ module ActiveRecord
|
|
1865
1901
|
def build_select(arel)
|
1866
1902
|
if select_values.any?
|
1867
1903
|
arel.project(*arel_columns(select_values))
|
1868
|
-
elsif
|
1869
|
-
arel.project(*
|
1904
|
+
elsif model.ignored_columns.any? || model.enumerate_columns_in_select_statements
|
1905
|
+
arel.project(*model.column_names.map { |field| table[field] })
|
1870
1906
|
else
|
1871
1907
|
arel.project(table[Arel.star])
|
1872
1908
|
end
|
@@ -1890,12 +1926,26 @@ module ActiveRecord
|
|
1890
1926
|
end
|
1891
1927
|
end
|
1892
1928
|
|
1893
|
-
def build_with_expression_from_value(value)
|
1929
|
+
def build_with_expression_from_value(value, nested = false)
|
1894
1930
|
case value
|
1895
1931
|
when Arel::Nodes::SqlLiteral then Arel::Nodes::Grouping.new(value)
|
1896
|
-
when ActiveRecord::Relation
|
1932
|
+
when ActiveRecord::Relation
|
1933
|
+
if nested
|
1934
|
+
value.arel.ast
|
1935
|
+
else
|
1936
|
+
value.arel
|
1937
|
+
end
|
1897
1938
|
when Arel::SelectManager then value
|
1898
|
-
when Array
|
1939
|
+
when Array
|
1940
|
+
return build_with_expression_from_value(value.first, false) if value.size == 1
|
1941
|
+
|
1942
|
+
parts = value.map do |query|
|
1943
|
+
build_with_expression_from_value(query, true)
|
1944
|
+
end
|
1945
|
+
|
1946
|
+
parts.reduce do |result, value|
|
1947
|
+
Arel::Nodes::UnionAll.new(result, value)
|
1948
|
+
end
|
1899
1949
|
else
|
1900
1950
|
raise ArgumentError, "Unsupported argument type: `#{value}` #{value.class}"
|
1901
1951
|
end
|
@@ -1905,48 +1955,53 @@ module ActiveRecord
|
|
1905
1955
|
with_table = Arel::Table.new(name)
|
1906
1956
|
|
1907
1957
|
table.join(with_table, kind).on(
|
1908
|
-
with_table[
|
1958
|
+
with_table[model.model_name.to_s.foreign_key].eq(table[model.primary_key])
|
1909
1959
|
).join_sources.first
|
1910
1960
|
end
|
1911
1961
|
|
1912
|
-
def
|
1913
|
-
|
1914
|
-
|
1915
|
-
|
1916
|
-
|
1917
|
-
|
1962
|
+
def arel_columns_from_hash(fields)
|
1963
|
+
fields.flat_map do |table_name, columns|
|
1964
|
+
table_name = table_name.name if table_name.is_a?(Symbol)
|
1965
|
+
case columns
|
1966
|
+
when Symbol, String
|
1967
|
+
arel_column_with_table(table_name, columns.to_s)
|
1968
|
+
when Array
|
1969
|
+
columns.map do |column|
|
1970
|
+
arel_column_with_table(table_name, column.to_s)
|
1918
1971
|
end
|
1919
|
-
when String
|
1920
|
-
arel_column(field, &:itself)
|
1921
|
-
when Proc
|
1922
|
-
field.call
|
1923
|
-
when Hash
|
1924
|
-
arel_columns_from_hash(field)
|
1925
1972
|
else
|
1926
|
-
|
1973
|
+
raise TypeError, "Expected Symbol, String or Array, got: #{columns.class}"
|
1927
1974
|
end
|
1928
1975
|
end
|
1929
1976
|
end
|
1930
1977
|
|
1978
|
+
def arel_column_with_table(table_name, column_name)
|
1979
|
+
self.references_values |= [Arel.sql(table_name, retryable: true)]
|
1980
|
+
predicate_builder.resolve_arel_attribute(table_name, column_name) do
|
1981
|
+
lookup_table_klass_from_join_dependencies(table_name)
|
1982
|
+
end
|
1983
|
+
end
|
1984
|
+
|
1931
1985
|
def arel_column(field)
|
1932
|
-
field =
|
1986
|
+
field = field.name if is_symbol = field.is_a?(Symbol)
|
1987
|
+
|
1988
|
+
field = model.attribute_aliases[field] || field
|
1933
1989
|
from = from_clause.name || from_clause.value
|
1934
1990
|
|
1935
|
-
if
|
1991
|
+
if model.columns_hash.key?(field) && (!from || table_name_matches?(from))
|
1936
1992
|
table[field]
|
1937
|
-
elsif
|
1938
|
-
table, column
|
1939
|
-
|
1940
|
-
lookup_table_klass_from_join_dependencies(table)
|
1941
|
-
end
|
1942
|
-
else
|
1993
|
+
elsif /\A(?<table>(?:\w+\.)?\w+)\.(?<column>\w+)\z/ =~ field
|
1994
|
+
arel_column_with_table(table, column)
|
1995
|
+
elsif block_given?
|
1943
1996
|
yield field
|
1997
|
+
else
|
1998
|
+
Arel.sql(is_symbol ? model.adapter_class.quote_table_name(field) : field)
|
1944
1999
|
end
|
1945
2000
|
end
|
1946
2001
|
|
1947
2002
|
def table_name_matches?(from)
|
1948
2003
|
table_name = Regexp.escape(table.name)
|
1949
|
-
quoted_table_name = Regexp.escape(adapter_class.quote_table_name(table.name))
|
2004
|
+
quoted_table_name = Regexp.escape(model.adapter_class.quote_table_name(table.name))
|
1950
2005
|
/(?:\A|(?<!FROM)\s)(?:\b#{table_name}\b|#{quoted_table_name})(?!\.)/i.match?(from.to_s)
|
1951
2006
|
end
|
1952
2007
|
|
@@ -2017,7 +2072,7 @@ module ActiveRecord
|
|
2017
2072
|
end
|
2018
2073
|
|
2019
2074
|
def preprocess_order_args(order_args)
|
2020
|
-
|
2075
|
+
model.disallow_raw_sql!(
|
2021
2076
|
flattened_args(order_args),
|
2022
2077
|
permit: model.adapter_class.column_name_with_order_matcher
|
2023
2078
|
)
|
@@ -2055,7 +2110,7 @@ module ActiveRecord
|
|
2055
2110
|
|
2056
2111
|
def sanitize_order_arguments(order_args)
|
2057
2112
|
order_args.map! do |arg|
|
2058
|
-
|
2113
|
+
model.sanitize_sql_for_order(arg)
|
2059
2114
|
end
|
2060
2115
|
end
|
2061
2116
|
|
@@ -2093,17 +2148,18 @@ module ActiveRecord
|
|
2093
2148
|
if attr_name == "count" && !group_values.empty?
|
2094
2149
|
table[attr_name]
|
2095
2150
|
else
|
2096
|
-
Arel.sql(adapter_class.quote_table_name(attr_name), retryable: true)
|
2151
|
+
Arel.sql(model.adapter_class.quote_table_name(attr_name), retryable: true)
|
2097
2152
|
end
|
2098
2153
|
end
|
2099
2154
|
end
|
2100
2155
|
|
2101
|
-
def build_case_for_value_position(column, values)
|
2156
|
+
def build_case_for_value_position(column, values, filter: true)
|
2102
2157
|
node = Arel::Nodes::Case.new
|
2103
2158
|
values.each.with_index(1) do |value, order|
|
2104
2159
|
node.when(column.eq(value)).then(order)
|
2105
2160
|
end
|
2106
2161
|
|
2162
|
+
node = node.else(values.length + 1) unless filter
|
2107
2163
|
Arel::Nodes::Ascending.new(node)
|
2108
2164
|
end
|
2109
2165
|
|
@@ -2161,34 +2217,29 @@ module ActiveRecord
|
|
2161
2217
|
def process_select_args(fields)
|
2162
2218
|
fields.flat_map do |field|
|
2163
2219
|
if field.is_a?(Hash)
|
2164
|
-
|
2220
|
+
arel_column_aliases_from_hash(field)
|
2165
2221
|
else
|
2166
2222
|
field
|
2167
2223
|
end
|
2168
2224
|
end
|
2169
2225
|
end
|
2170
2226
|
|
2171
|
-
def
|
2227
|
+
def arel_column_aliases_from_hash(fields)
|
2172
2228
|
fields.flat_map do |key, columns_aliases|
|
2229
|
+
table_name = key.is_a?(Symbol) ? key.name : key
|
2173
2230
|
case columns_aliases
|
2174
2231
|
when Hash
|
2175
2232
|
columns_aliases.map do |column, column_alias|
|
2176
|
-
|
2177
|
-
|
2178
|
-
self.references_values |= references unless references.empty?
|
2179
|
-
end
|
2180
|
-
arel_column("#{key}.#{column}") do
|
2181
|
-
predicate_builder.resolve_arel_attribute(key.to_s, column)
|
2182
|
-
end.as(column_alias.to_s)
|
2233
|
+
arel_column_with_table(table_name, column.to_s)
|
2234
|
+
.as(model.adapter_class.quote_column_name(column_alias.to_s))
|
2183
2235
|
end
|
2184
2236
|
when Array
|
2185
2237
|
columns_aliases.map do |column|
|
2186
|
-
|
2238
|
+
arel_column_with_table(table_name, column.to_s)
|
2187
2239
|
end
|
2188
2240
|
when String, Symbol
|
2189
|
-
arel_column(key
|
2190
|
-
|
2191
|
-
end.as(columns_aliases.to_s)
|
2241
|
+
arel_column(key)
|
2242
|
+
.as(model.adapter_class.quote_column_name(columns_aliases.to_s))
|
2192
2243
|
end
|
2193
2244
|
end
|
2194
2245
|
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.
|