activerecord 7.2.0 → 7.2.2.1

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +196 -0
  3. data/lib/active_record/associations/has_many_through_association.rb +7 -1
  4. data/lib/active_record/associations/join_dependency/join_association.rb +3 -2
  5. data/lib/active_record/associations/join_dependency.rb +5 -5
  6. data/lib/active_record/associations.rb +28 -16
  7. data/lib/active_record/attribute_assignment.rb +9 -1
  8. data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -0
  9. data/lib/active_record/attributes.rb +6 -5
  10. data/lib/active_record/callbacks.rb +1 -1
  11. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +49 -43
  12. data/lib/active_record/connection_adapters/abstract/query_cache.rb +45 -16
  13. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +1 -1
  14. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +7 -3
  15. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +1 -1
  16. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
  17. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +2 -0
  18. data/lib/active_record/connection_adapters/postgresql_adapter.rb +3 -3
  19. data/lib/active_record/core.rb +41 -9
  20. data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -1
  21. data/lib/active_record/encryption/encryptable_record.rb +1 -1
  22. data/lib/active_record/encryption/encrypted_attribute_type.rb +2 -2
  23. data/lib/active_record/encryption/encryptor.rb +1 -1
  24. data/lib/active_record/encryption/key_provider.rb +1 -1
  25. data/lib/active_record/encryption.rb +2 -0
  26. data/lib/active_record/enum.rb +8 -0
  27. data/lib/active_record/gem_version.rb +2 -2
  28. data/lib/active_record/marshalling.rb +4 -1
  29. data/lib/active_record/model_schema.rb +5 -2
  30. data/lib/active_record/nested_attributes.rb +13 -2
  31. data/lib/active_record/query_cache.rb +4 -5
  32. data/lib/active_record/query_logs.rb +1 -1
  33. data/lib/active_record/railtie.rb +7 -12
  34. data/lib/active_record/reflection.rb +15 -8
  35. data/lib/active_record/relation/batches.rb +4 -4
  36. data/lib/active_record/relation/calculations.rb +1 -1
  37. data/lib/active_record/relation/predicate_builder.rb +1 -1
  38. data/lib/active_record/relation/query_methods.rb +39 -24
  39. data/lib/active_record/scoping/named.rb +1 -0
  40. data/lib/active_record/tasks/database_tasks.rb +12 -1
  41. data/lib/active_record/testing/query_assertions.rb +2 -2
  42. data/lib/active_record/validations/uniqueness.rb +1 -0
  43. data/lib/arel/visitors/sqlite.rb +25 -0
  44. metadata +13 -13
@@ -142,7 +142,7 @@ module ActiveRecord
142
142
  queries.first
143
143
  else
144
144
  queries.map! { |query| query.reduce(&:and) }
145
- queries = queries.reduce { |result, query| Arel::Nodes::Or.new([result, query]) }
145
+ queries = Arel::Nodes::Or.new(queries)
146
146
  Arel::Nodes::Grouping.new(queries)
147
147
  end
148
148
  end
@@ -1636,6 +1636,26 @@ module ActiveRecord
1636
1636
  self
1637
1637
  end
1638
1638
 
1639
+ protected
1640
+ def arel_columns(columns)
1641
+ columns.flat_map do |field|
1642
+ case field
1643
+ when Symbol
1644
+ arel_column(field.to_s) do |attr_name|
1645
+ adapter_class.quote_table_name(attr_name)
1646
+ end
1647
+ when String
1648
+ arel_column(field, &:itself)
1649
+ when Proc
1650
+ field.call
1651
+ when Hash
1652
+ arel_columns_from_hash(field)
1653
+ else
1654
+ field
1655
+ end
1656
+ end
1657
+ end
1658
+
1639
1659
  private
1640
1660
  def async
1641
1661
  spawn.async!
@@ -1890,12 +1910,26 @@ module ActiveRecord
1890
1910
  end
1891
1911
  end
1892
1912
 
1893
- def build_with_expression_from_value(value)
1913
+ def build_with_expression_from_value(value, nested = false)
1894
1914
  case value
1895
1915
  when Arel::Nodes::SqlLiteral then Arel::Nodes::Grouping.new(value)
1896
- when ActiveRecord::Relation then value.arel
1916
+ when ActiveRecord::Relation
1917
+ if nested
1918
+ value.arel.ast
1919
+ else
1920
+ value.arel
1921
+ end
1897
1922
  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) }
1923
+ when Array
1924
+ return build_with_expression_from_value(value.first, false) if value.size == 1
1925
+
1926
+ parts = value.map do |query|
1927
+ build_with_expression_from_value(query, true)
1928
+ end
1929
+
1930
+ parts.reduce do |result, value|
1931
+ Arel::Nodes::UnionAll.new(result, value)
1932
+ end
1899
1933
  else
1900
1934
  raise ArgumentError, "Unsupported argument type: `#{value}` #{value.class}"
1901
1935
  end
@@ -1909,33 +1943,14 @@ module ActiveRecord
1909
1943
  ).join_sources.first
1910
1944
  end
1911
1945
 
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)
1918
- 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
- else
1926
- field
1927
- end
1928
- end
1929
- end
1930
-
1931
1946
  def arel_column(field)
1932
1947
  field = klass.attribute_aliases[field] || field
1933
1948
  from = from_clause.name || from_clause.value
1934
1949
 
1935
1950
  if klass.columns_hash.key?(field) && (!from || table_name_matches?(from))
1936
1951
  table[field]
1937
- elsif field.match?(/\A\w+\.\w+\z/)
1938
- table, column = field.split(".")
1952
+ elsif /\A(?<table>(?:\w+\.)?\w+)\.(?<column>\w+)\z/ =~ field
1953
+ self.references_values |= [Arel.sql(table, retryable: true)]
1939
1954
  predicate_builder.resolve_arel_attribute(table, column) do
1940
1955
  lookup_table_klass_from_join_dependencies(table)
1941
1956
  end
@@ -190,6 +190,7 @@ module ActiveRecord
190
190
 
191
191
  private
192
192
  def singleton_method_added(name)
193
+ super
193
194
  generate_relation_method(name) if Kernel.respond_to?(name) && !ActiveRecord::Relation.method_defined?(name)
194
195
  end
195
196
  end
@@ -175,6 +175,7 @@ module ActiveRecord
175
175
 
176
176
  def prepare_all
177
177
  seed = false
178
+ dump_db_configs = []
178
179
 
179
180
  each_current_configuration(env) do |db_config|
180
181
  with_temporary_pool(db_config) do
@@ -197,15 +198,25 @@ module ActiveRecord
197
198
 
198
199
  each_current_environment(env) do |environment|
199
200
  db_configs_with_versions(environment).sort.each do |version, db_configs|
201
+ dump_db_configs |= db_configs
202
+
200
203
  db_configs.each do |db_config|
201
204
  with_temporary_pool(db_config) do
202
205
  migrate(version)
203
- dump_schema(db_config) if ActiveRecord.dump_schema_after_migration
204
206
  end
205
207
  end
206
208
  end
207
209
  end
208
210
 
211
+ # Dump schema for databases that were migrated.
212
+ if ActiveRecord.dump_schema_after_migration
213
+ dump_db_configs.each do |db_config|
214
+ with_temporary_pool(db_config) do
215
+ dump_schema(db_config)
216
+ end
217
+ end
218
+ end
219
+
209
220
  load_seed if seed
210
221
  end
211
222
 
@@ -52,7 +52,7 @@ module ActiveRecord
52
52
  # assert_queries_match(/LIMIT \?/) { Post.first }
53
53
  #
54
54
  # If the +:include_schema+ option is provided, any queries (including schema related)
55
- # that match the matcher are considered.
55
+ # that match the matcher are considered.
56
56
  #
57
57
  # assert_queries_match(/FROM pg_attribute/i, include_schema: true) { Post.columns }
58
58
  #
@@ -80,7 +80,7 @@ module ActiveRecord
80
80
  # assert_no_queries_match(/SELECT/i) { post.comments }
81
81
  #
82
82
  # If the +:include_schema+ option is provided, any queries (including schema related)
83
- # that match the matcher are counted.
83
+ # that match the matcher are counted.
84
84
  #
85
85
  # assert_no_queries_match(/FROM pg_attribute/i, include_schema: true) { Post.columns }
86
86
  #
@@ -14,6 +14,7 @@ module ActiveRecord
14
14
  end
15
15
  super
16
16
  @klass = options[:class]
17
+ @klass = @klass.superclass if @klass.singleton_class?
17
18
  end
18
19
 
19
20
  def validate_each(record, attribute, value)
@@ -33,6 +33,31 @@ module Arel # :nodoc: all
33
33
  collector << " IS NOT "
34
34
  visit o.right, collector
35
35
  end
36
+
37
+ # Queries used in UNION should not be wrapped by parentheses,
38
+ # because it is an invalid syntax in SQLite.
39
+ def infix_value_with_paren(o, collector, value, suppress_parens = false)
40
+ collector << "( " unless suppress_parens
41
+
42
+ left = o.left.is_a?(Nodes::Grouping) ? o.left.expr : o.left
43
+ collector = if left.class == o.class
44
+ infix_value_with_paren(left, collector, value, true)
45
+ else
46
+ grouping_parentheses left, collector, false
47
+ end
48
+
49
+ collector << value
50
+
51
+ right = o.right.is_a?(Nodes::Grouping) ? o.right.expr : o.right
52
+ collector = if right.class == o.class
53
+ infix_value_with_paren(right, collector, value, true)
54
+ else
55
+ grouping_parentheses right, collector, false
56
+ end
57
+
58
+ collector << " )" unless suppress_parens
59
+ collector
60
+ end
36
61
  end
37
62
  end
38
63
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.2.0
4
+ version: 7.2.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-09 00:00:00.000000000 Z
11
+ date: 2024-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 7.2.0
19
+ version: 7.2.2.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 7.2.0
26
+ version: 7.2.2.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activemodel
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 7.2.0
33
+ version: 7.2.2.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 7.2.0
40
+ version: 7.2.2.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: timeout
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -476,12 +476,12 @@ licenses:
476
476
  - MIT
477
477
  metadata:
478
478
  bug_tracker_uri: https://github.com/rails/rails/issues
479
- changelog_uri: https://github.com/rails/rails/blob/v7.2.0/activerecord/CHANGELOG.md
480
- documentation_uri: https://api.rubyonrails.org/v7.2.0/
479
+ changelog_uri: https://github.com/rails/rails/blob/v7.2.2.1/activerecord/CHANGELOG.md
480
+ documentation_uri: https://api.rubyonrails.org/v7.2.2.1/
481
481
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
482
- source_code_uri: https://github.com/rails/rails/tree/v7.2.0/activerecord
482
+ source_code_uri: https://github.com/rails/rails/tree/v7.2.2.1/activerecord
483
483
  rubygems_mfa_required: 'true'
484
- post_install_message:
484
+ post_install_message:
485
485
  rdoc_options:
486
486
  - "--main"
487
487
  - README.rdoc
@@ -498,8 +498,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
498
498
  - !ruby/object:Gem::Version
499
499
  version: '0'
500
500
  requirements: []
501
- rubygems_version: 3.5.11
502
- signing_key:
501
+ rubygems_version: 3.5.22
502
+ signing_key:
503
503
  specification_version: 4
504
504
  summary: Object-relational mapper framework (part of Rails).
505
505
  test_files: []