activerecord 7.2.1.1 → 8.0.0.rc1
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 +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.
|