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.
Files changed (123) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +220 -756
  3. data/README.rdoc +1 -1
  4. data/lib/active_record/associations/association.rb +25 -5
  5. data/lib/active_record/associations/builder/association.rb +7 -6
  6. data/lib/active_record/associations/collection_association.rb +10 -8
  7. data/lib/active_record/associations/disable_joins_association_scope.rb +1 -1
  8. data/lib/active_record/associations/has_many_through_association.rb +10 -3
  9. data/lib/active_record/associations/join_dependency/join_association.rb +3 -2
  10. data/lib/active_record/associations/join_dependency.rb +4 -4
  11. data/lib/active_record/associations/preloader/association.rb +2 -2
  12. data/lib/active_record/associations/singular_association.rb +8 -3
  13. data/lib/active_record/associations.rb +34 -4
  14. data/lib/active_record/asynchronous_queries_tracker.rb +28 -24
  15. data/lib/active_record/attribute_assignment.rb +9 -1
  16. data/lib/active_record/attribute_methods/primary_key.rb +2 -7
  17. data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -12
  18. data/lib/active_record/attributes.rb +1 -2
  19. data/lib/active_record/autosave_association.rb +69 -27
  20. data/lib/active_record/callbacks.rb +1 -1
  21. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +16 -10
  22. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +0 -1
  23. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +0 -1
  24. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +26 -9
  25. data/lib/active_record/connection_adapters/abstract/database_statements.rb +90 -43
  26. data/lib/active_record/connection_adapters/abstract/query_cache.rb +12 -4
  27. data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -1
  28. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -5
  29. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +7 -2
  30. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +34 -7
  31. data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -5
  32. data/lib/active_record/connection_adapters/abstract_adapter.rb +24 -26
  33. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +28 -42
  34. data/lib/active_record/connection_adapters/mysql/quoting.rb +0 -8
  35. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +2 -8
  36. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +43 -45
  37. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +42 -98
  38. data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -8
  39. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -42
  40. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  41. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
  42. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +10 -0
  43. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -4
  44. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +0 -11
  45. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -11
  46. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +1 -1
  47. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +54 -14
  48. data/lib/active_record/connection_adapters/postgresql_adapter.rb +45 -97
  49. data/lib/active_record/connection_adapters/schema_cache.rb +1 -3
  50. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +76 -100
  51. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +0 -6
  52. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +13 -0
  53. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +8 -1
  54. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +53 -12
  55. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +37 -67
  56. data/lib/active_record/connection_adapters/trilogy_adapter.rb +0 -17
  57. data/lib/active_record/connection_adapters.rb +0 -56
  58. data/lib/active_record/connection_handling.rb +22 -0
  59. data/lib/active_record/core.rb +28 -18
  60. data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -1
  61. data/lib/active_record/encryption/config.rb +3 -1
  62. data/lib/active_record/encryption/encryptable_record.rb +4 -4
  63. data/lib/active_record/encryption/encrypted_attribute_type.rb +10 -1
  64. data/lib/active_record/encryption/encryptor.rb +15 -8
  65. data/lib/active_record/encryption/extended_deterministic_queries.rb +4 -2
  66. data/lib/active_record/encryption/key_provider.rb +1 -1
  67. data/lib/active_record/encryption/scheme.rb +8 -1
  68. data/lib/active_record/encryption.rb +2 -0
  69. data/lib/active_record/enum.rb +54 -75
  70. data/lib/active_record/errors.rb +13 -5
  71. data/lib/active_record/fixtures.rb +0 -2
  72. data/lib/active_record/future_result.rb +14 -10
  73. data/lib/active_record/gem_version.rb +4 -4
  74. data/lib/active_record/insert_all.rb +1 -1
  75. data/lib/active_record/locking/optimistic.rb +1 -1
  76. data/lib/active_record/log_subscriber.rb +5 -11
  77. data/lib/active_record/marshalling.rb +4 -1
  78. data/lib/active_record/migration/command_recorder.rb +22 -5
  79. data/lib/active_record/migration/compatibility.rb +5 -2
  80. data/lib/active_record/migration.rb +35 -38
  81. data/lib/active_record/model_schema.rb +4 -6
  82. data/lib/active_record/nested_attributes.rb +11 -2
  83. data/lib/active_record/persistence.rb +128 -130
  84. data/lib/active_record/query_cache.rb +0 -4
  85. data/lib/active_record/query_logs.rb +102 -50
  86. data/lib/active_record/query_logs_formatter.rb +17 -28
  87. data/lib/active_record/querying.rb +8 -8
  88. data/lib/active_record/railtie.rb +9 -38
  89. data/lib/active_record/railties/databases.rake +1 -1
  90. data/lib/active_record/reflection.rb +23 -23
  91. data/lib/active_record/relation/batches/batch_enumerator.rb +4 -3
  92. data/lib/active_record/relation/batches.rb +132 -72
  93. data/lib/active_record/relation/calculations.rb +41 -40
  94. data/lib/active_record/relation/delegation.rb +25 -14
  95. data/lib/active_record/relation/finder_methods.rb +18 -18
  96. data/lib/active_record/relation/merger.rb +8 -8
  97. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -1
  98. data/lib/active_record/relation/predicate_builder/relation_handler.rb +4 -3
  99. data/lib/active_record/relation/predicate_builder.rb +14 -1
  100. data/lib/active_record/relation/query_methods.rb +122 -71
  101. data/lib/active_record/relation/spawn_methods.rb +1 -1
  102. data/lib/active_record/relation.rb +79 -61
  103. data/lib/active_record/result.rb +66 -4
  104. data/lib/active_record/sanitization.rb +7 -6
  105. data/lib/active_record/schema_dumper.rb +5 -0
  106. data/lib/active_record/schema_migration.rb +2 -1
  107. data/lib/active_record/scoping/named.rb +5 -2
  108. data/lib/active_record/statement_cache.rb +12 -12
  109. data/lib/active_record/store.rb +7 -3
  110. data/lib/active_record/table_metadata.rb +1 -3
  111. data/lib/active_record/tasks/database_tasks.rb +40 -47
  112. data/lib/active_record/tasks/mysql_database_tasks.rb +0 -2
  113. data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -2
  114. data/lib/active_record/test_fixtures.rb +12 -0
  115. data/lib/active_record/testing/query_assertions.rb +2 -2
  116. data/lib/active_record/token_for.rb +1 -1
  117. data/lib/active_record/validations/uniqueness.rb +9 -8
  118. data/lib/active_record.rb +15 -45
  119. data/lib/arel/collectors/bind.rb +1 -1
  120. data/lib/arel/table.rb +3 -7
  121. data/lib/arel/visitors/sqlite.rb +25 -0
  122. metadata +10 -11
  123. 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 => { reflection.association_primary_key => nil })
97
+ self.not(association => association_conditions)
97
98
  else
98
- self.not(reflection.table_name => { reflection.association_primary_key => nil })
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 => { reflection.association_primary_key => nil })
130
+ @scope.where!(association => association_conditions)
129
131
  else
130
- @scope.where!(reflection.table_name => { reflection.association_primary_key => nil })
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
- reflection = @scope.klass._reflect_on_association(association)
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 `#{@scope.name}`.")
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
- def in_order_of(column, values)
700
- klass.disallow_raw_sql!([column], permit: model.adapter_class.column_name_with_order_matcher)
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
- where_clause =
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
- spawn
717
- .order!(build_case_for_value_position(arel_column, values))
718
- .where!(where_clause)
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?(klass) && relations.all? { |relation| relation.klass == klass }
1558
- raise ArgumentError, "You must only pass a single or collection of #{klass.name} objects to ##{__callee__}."
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
- klass, table, associations, join_type
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 = [klass.sanitize_sql(rest.empty? ? opts : [opts, *rest])]
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| klass.attribute_aliases[k.to_s] || k.to_s }
1632
+ key.map { |k| model.attribute_aliases[k.to_s] || k.to_s }
1613
1633
  else
1614
1634
  key = key.to_s
1615
- klass.attribute_aliases[key] || key
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 == 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 klass.ignored_columns.any? || klass.enumerate_columns_in_select_statements
1869
- arel.project(*klass.column_names.map { |field| table[field] })
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 then value.arel
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 then value.map { |q| build_with_expression_from_value(q) }.reduce { |result, value| result.union(:all, value) }
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[klass.model_name.to_s.foreign_key].eq(table[klass.primary_key])
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 arel_columns(columns)
1913
- columns.flat_map do |field|
1914
- case field
1915
- when Symbol
1916
- arel_column(field.to_s) do |attr_name|
1917
- adapter_class.quote_table_name(attr_name)
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
- field
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 = klass.attribute_aliases[field] || 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 klass.columns_hash.key?(field) && (!from || table_name_matches?(from))
1991
+ if model.columns_hash.key?(field) && (!from || table_name_matches?(from))
1936
1992
  table[field]
1937
- elsif field.match?(/\A\w+\.\w+\z/)
1938
- table, column = field.split(".")
1939
- predicate_builder.resolve_arel_attribute(table, column) do
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
- @klass.disallow_raw_sql!(
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
- klass.sanitize_sql_for_order(arg)
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
- arel_columns_from_hash(field)
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 arel_columns_from_hash(fields)
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
- if values[:joins]&.include?(key)
2177
- references = PredicateBuilder.references({ key.to_s => fields[key] })
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
- arel_column("#{key}.#{column}", &:itself)
2238
+ arel_column_with_table(table_name, column.to_s)
2187
2239
  end
2188
2240
  when String, Symbol
2189
- arel_column(key.to_s) do
2190
- predicate_builder.resolve_arel_attribute(klass.table_name, key.to_s)
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?(klass.scope_registry) ? klass.all : clone
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.