activerecord 7.1.0.beta1 → 7.1.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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +70 -4
  3. data/lib/active_record/associations/collection_association.rb +1 -3
  4. data/lib/active_record/associations/collection_proxy.rb +1 -1
  5. data/lib/active_record/associations.rb +107 -107
  6. data/lib/active_record/connection_adapters/abstract/database_statements.rb +20 -1
  7. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +3 -3
  8. data/lib/active_record/connection_adapters/abstract/transaction.rb +12 -9
  9. data/lib/active_record/connection_adapters/abstract_adapter.rb +1 -1
  10. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +7 -0
  11. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +1 -1
  12. data/lib/active_record/connection_adapters/pool_manager.rb +1 -1
  13. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +0 -16
  14. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +5 -5
  15. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -24
  16. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +19 -8
  17. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +25 -29
  18. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -6
  19. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +4 -4
  20. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +49 -4
  21. data/lib/active_record/core.rb +7 -9
  22. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +1 -1
  23. data/lib/active_record/errors.rb +19 -0
  24. data/lib/active_record/gem_version.rb +1 -1
  25. data/lib/active_record/migration/command_recorder.rb +8 -8
  26. data/lib/active_record/normalization.rb +2 -1
  27. data/lib/active_record/railtie.rb +1 -1
  28. data/lib/active_record/reflection.rb +10 -16
  29. data/lib/active_record/relation/finder_methods.rb +3 -12
  30. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -6
  31. data/lib/active_record/schema_dumper.rb +9 -4
  32. metadata +9 -9
@@ -344,11 +344,6 @@ module ActiveRecord
344
344
  end
345
345
  end
346
346
 
347
- # Override the default class equality method to provide support for decorated models.
348
- def ===(object) # :nodoc:
349
- object.is_a?(self)
350
- end
351
-
352
347
  # Returns an instance of +Arel::Table+ loaded with the current table name.
353
348
  def arel_table # :nodoc:
354
349
  @arel_table ||= Arel::Table.new(table_name, klass: self)
@@ -615,7 +610,9 @@ module ActiveRecord
615
610
  #
616
611
  # user = User.first
617
612
  # user.strict_loading! # => true
618
- # user.comments
613
+ # user.address.city
614
+ # => ActiveRecord::StrictLoadingViolationError
615
+ # user.comments.to_a
619
616
  # => ActiveRecord::StrictLoadingViolationError
620
617
  #
621
618
  # ==== Parameters
@@ -629,12 +626,13 @@ module ActiveRecord
629
626
  #
630
627
  # user = User.first
631
628
  # user.strict_loading!(false) # => false
632
- # user.comments
633
- # => #<ActiveRecord::Associations::CollectionProxy>
629
+ # user.address.city # => "Tatooine"
630
+ # user.comments.to_a # => [#<Comment:0x00...]
634
631
  #
635
632
  # user.strict_loading!(mode: :n_plus_one_only)
636
633
  # user.address.city # => "Tatooine"
637
- # user.comments
634
+ # user.comments.to_a # => [#<Comment:0x00...]
635
+ # user.comments.first.ratings.to_a
638
636
  # => ActiveRecord::StrictLoadingViolationError
639
637
  def strict_loading!(value = true, mode: :all)
640
638
  unless [:all, :n_plus_one_only].include?(mode)
@@ -14,7 +14,7 @@ module ActiveRecord
14
14
  klass = record.class
15
15
  if klass.deterministic_encrypted_attributes&.include?(attribute)
16
16
  encrypted_type = klass.type_for_attribute(attribute)
17
- [ encrypted_type, *encrypted_type.previous_types ].each do |type|
17
+ encrypted_type.previous_types.each do |type|
18
18
  encrypted_value = type.serialize(value)
19
19
  ActiveRecord::Encryption.without_encryption do
20
20
  super(record, attribute, encrypted_value)
@@ -483,6 +483,19 @@ module ActiveRecord
483
483
  # TransactionRollbackError will be raised when a transaction is rolled
484
484
  # back by the database due to a serialization failure or a deadlock.
485
485
  #
486
+ # These exceptions should not be generally rescued in nested transaction
487
+ # blocks, because they have side-effects in the actual enclosing transaction
488
+ # and internal Active Record state. They can be rescued if you are above the
489
+ # root transaction block, though.
490
+ #
491
+ # In that case, beware of transactional tests, however, because they run test
492
+ # cases in their own umbrella transaction. If you absolutely need to handle
493
+ # these exceptions in tests please consider disabling transactional tests in
494
+ # the affected test class (<tt>self.use_transactional_tests = false</tt>).
495
+ #
496
+ # Due to the aforementioned side-effects, this exception should not be raised
497
+ # manually by users.
498
+ #
486
499
  # See the following:
487
500
  #
488
501
  # * https://www.postgresql.org/docs/current/static/transaction-iso.html
@@ -497,11 +510,17 @@ module ActiveRecord
497
510
 
498
511
  # SerializationFailure will be raised when a transaction is rolled
499
512
  # back by the database due to a serialization failure.
513
+ #
514
+ # This is a subclass of TransactionRollbackError, please make sure to check
515
+ # its documentation to be aware of its caveats.
500
516
  class SerializationFailure < TransactionRollbackError
501
517
  end
502
518
 
503
519
  # Deadlocked will be raised when a transaction is rolled
504
520
  # back by the database when a deadlock is encountered.
521
+ #
522
+ # This is a subclass of TransactionRollbackError, please make sure to check
523
+ # its documentation to be aware of its caveats.
505
524
  class Deadlocked < TransactionRollbackError
506
525
  end
507
526
 
@@ -10,7 +10,7 @@ module ActiveRecord
10
10
  MAJOR = 7
11
11
  MINOR = 1
12
12
  TINY = 0
13
- PRE = "beta1"
13
+ PRE = "rc1"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -12,7 +12,7 @@ module ActiveRecord
12
12
  # * add_foreign_key
13
13
  # * add_check_constraint
14
14
  # * add_exclusion_constraint
15
- # * add_unique_key
15
+ # * add_unique_constraint
16
16
  # * add_index
17
17
  # * add_reference
18
18
  # * add_timestamps
@@ -33,7 +33,7 @@ module ActiveRecord
33
33
  # * remove_foreign_key (must supply a second table)
34
34
  # * remove_check_constraint
35
35
  # * remove_exclusion_constraint
36
- # * remove_unique_key
36
+ # * remove_unique_constraint
37
37
  # * remove_index
38
38
  # * remove_reference
39
39
  # * remove_timestamps
@@ -53,7 +53,7 @@ module ActiveRecord
53
53
  :change_column_comment, :change_table_comment,
54
54
  :add_check_constraint, :remove_check_constraint,
55
55
  :add_exclusion_constraint, :remove_exclusion_constraint,
56
- :add_unique_key, :remove_unique_key,
56
+ :add_unique_constraint, :remove_unique_constraint,
57
57
  :create_enum, :drop_enum, :rename_enum, :add_enum_value, :rename_enum_value,
58
58
  ]
59
59
  include JoinTable
@@ -161,7 +161,7 @@ module ActiveRecord
161
161
  add_foreign_key: :remove_foreign_key,
162
162
  add_check_constraint: :remove_check_constraint,
163
163
  add_exclusion_constraint: :remove_exclusion_constraint,
164
- add_unique_key: :remove_unique_key,
164
+ add_unique_constraint: :remove_unique_constraint,
165
165
  enable_extension: :disable_extension,
166
166
  create_enum: :drop_enum
167
167
  }.each do |cmd, inv|
@@ -329,17 +329,17 @@ module ActiveRecord
329
329
  super
330
330
  end
331
331
 
332
- def invert_add_unique_key(args)
332
+ def invert_add_unique_constraint(args)
333
333
  options = args.dup.extract_options!
334
334
 
335
- raise ActiveRecord::IrreversibleMigration, "add_unique_key is not reversible if given an using_index." if options[:using_index]
335
+ raise ActiveRecord::IrreversibleMigration, "add_unique_constraint is not reversible if given an using_index." if options[:using_index]
336
336
  super
337
337
  end
338
338
 
339
- def invert_remove_unique_key(args)
339
+ def invert_remove_unique_constraint(args)
340
340
  _table, columns = args.dup.tap(&:extract_options!)
341
341
 
342
- raise ActiveRecord::IrreversibleMigration, "remove_unique_key is only reversible if given an column_name." if columns.blank?
342
+ raise ActiveRecord::IrreversibleMigration, "remove_unique_constraint is only reversible if given an column_name." if columns.blank?
343
343
  super
344
344
  end
345
345
 
@@ -51,7 +51,8 @@ module ActiveRecord # :nodoc:
51
51
  #
52
52
  # ==== Options
53
53
  #
54
- # * +:with+ - The normalization to apply.
54
+ # * +:with+ - Any callable object that accepts the attribute's value as
55
+ # its sole argument, and returns it normalized.
55
56
  # * +:apply_to_nil+ - Whether to apply the normalization to +nil+ values.
56
57
  # Defaults to +false+.
57
58
  #
@@ -67,7 +67,7 @@ module ActiveRecord
67
67
  unless ActiveSupport::Logger.logger_outputs_to?(Rails.logger, STDERR, STDOUT)
68
68
  console = ActiveSupport::Logger.new(STDERR)
69
69
  console.level = Rails.logger.level
70
- Rails.logger.extend ActiveSupport::Logger.broadcast console
70
+ Rails.logger = ActiveSupport::BroadcastLogger.new(Rails.logger, console)
71
71
  end
72
72
  ActiveRecord.verbose_query_logs = false
73
73
  end
@@ -507,7 +507,7 @@ module ActiveRecord
507
507
  derived_fk = derive_foreign_key(infer_from_inverse_of: infer_from_inverse_of)
508
508
 
509
509
  if active_record.has_query_constraints?
510
- derived_fk = derive_fk_query_constraints(active_record, derived_fk)
510
+ derived_fk = derive_fk_query_constraints(derived_fk)
511
511
  end
512
512
 
513
513
  derived_fk
@@ -770,13 +770,13 @@ module ActiveRecord
770
770
  end
771
771
  end
772
772
 
773
- def derive_fk_query_constraints(klass, foreign_key)
774
- primary_query_constraints = klass.query_constraints_list
775
- owner_pk = klass.primary_key
773
+ def derive_fk_query_constraints(foreign_key)
774
+ primary_query_constraints = active_record.query_constraints_list
775
+ owner_pk = active_record.primary_key
776
776
 
777
777
  if primary_query_constraints.size != 2
778
778
  raise ArgumentError, <<~MSG.squish
779
- The query constraints list on the `#{klass}` model has more than 2
779
+ The query constraints list on the `#{active_record}` model has more than 2
780
780
  attributes. Active Record is unable to derive the query constraints
781
781
  for the association. You need to explicitly define the query constraints
782
782
  for this association.
@@ -785,19 +785,13 @@ module ActiveRecord
785
785
 
786
786
  if !primary_query_constraints.include?(owner_pk)
787
787
  raise ArgumentError, <<~MSG.squish
788
- The query constraints on the `#{klass}` model does not include the primary
788
+ The query constraints on the `#{active_record}` model does not include the primary
789
789
  key so Active Record is unable to derive the foreign key constraints for
790
790
  the association. You need to explicitly define the query constraints for this
791
791
  association.
792
792
  MSG
793
793
  end
794
794
 
795
- # The primary key and foreign key are both already in the query constraints
796
- # so we don't want to derive the key. In this case we want a single key.
797
- if primary_query_constraints.include?(owner_pk) && primary_query_constraints.include?(foreign_key)
798
- return foreign_key
799
- end
800
-
801
795
  first_key, last_key = primary_query_constraints
802
796
 
803
797
  if first_key == owner_pk
@@ -807,7 +801,7 @@ module ActiveRecord
807
801
  else
808
802
  raise ArgumentError, <<~MSG.squish
809
803
  Active Record couldn't correctly interpret the query constraints
810
- for the `#{klass}` model. The query constraints on `#{klass}` are
804
+ for the `#{active_record}` model. The query constraints on `#{active_record}` are
811
805
  `#{primary_query_constraints}` and the foreign key is `#{foreign_key}`.
812
806
  You need to explicitly set the query constraints for this association.
813
807
  MSG
@@ -862,10 +856,10 @@ module ActiveRecord
862
856
 
863
857
  # klass option is necessary to support loading polymorphic associations
864
858
  def association_primary_key(klass = nil)
865
- if !polymorphic? && ((klass || self.klass).has_query_constraints? || options[:query_constraints])
866
- (klass || self.klass).composite_query_constraints_list
867
- elsif primary_key = options[:primary_key]
859
+ if primary_key = options[:primary_key]
868
860
  @association_primary_key ||= -primary_key.to_s
861
+ elsif !polymorphic? && ((klass || self.klass).has_query_constraints? || options[:query_constraints])
862
+ (klass || self.klass).composite_query_constraints_list
869
863
  elsif (klass || self.klass).composite_primary_key?
870
864
  # If klass has composite primary key of shape [:<tenant_key>, :id], infer primary_key as :id
871
865
  primary_key = (klass || self.klass).primary_key
@@ -16,7 +16,7 @@ module ActiveRecord
16
16
  # Person.find("1") # returns the object for ID = 1
17
17
  # Person.find("31-sarah") # returns the object for ID = 31
18
18
  # Person.find(1, 2, 6) # returns an array for objects with IDs in (1, 2, 6)
19
- # Person.find([7, 17]) # returns an array for objects with IDs in (7, 17)
19
+ # Person.find([7, 17]) # returns an array for objects with IDs in (7, 17), or with composite primary key [7, 17]
20
20
  # Person.find([1]) # returns an array for the object with ID = 1
21
21
  # Person.where("administrator = 1").order("created_on DESC").find(1)
22
22
  #
@@ -527,12 +527,7 @@ module ActiveRecord
527
527
  def find_some(ids)
528
528
  return find_some_ordered(ids) unless order_values.present?
529
529
 
530
- relation = if klass.composite_primary_key?
531
- ids.map { |values_set| where(primary_key.zip(values_set).to_h) }.inject(&:or)
532
- else
533
- where(primary_key => ids)
534
- end
535
-
530
+ relation = where(primary_key => ids)
536
531
  relation = relation.select(table[primary_key]) unless select_values.empty?
537
532
  result = relation.to_a
538
533
 
@@ -559,11 +554,7 @@ module ActiveRecord
559
554
  ids = ids.slice(offset_value || 0, limit_value || ids.size) || []
560
555
 
561
556
  relation = except(:limit, :offset)
562
- relation = if klass.composite_primary_key?
563
- ids.map { |values_set| relation.where(primary_key.zip(values_set).to_h) }.inject(&:or)
564
- else
565
- relation.where(primary_key => ids)
566
- end
557
+ relation = relation.where(primary_key => ids)
567
558
  relation = relation.select(table[primary_key]) unless select_values.empty?
568
559
  result = relation.records
569
560
 
@@ -34,19 +34,17 @@ module ActiveRecord
34
34
  end
35
35
 
36
36
  def klass(value)
37
- case value
38
- when Base
37
+ if value.is_a?(Base)
39
38
  value.class
40
- when Relation
39
+ elsif value.is_a?(Relation)
41
40
  value.klass
42
41
  end
43
42
  end
44
43
 
45
44
  def convert_to_id(value)
46
- case value
47
- when Base
45
+ if value.is_a?(Base)
48
46
  value._read_attribute(primary_key(value))
49
- when Relation
47
+ elsif value.is_a?(Relation)
50
48
  value.select(primary_key(value))
51
49
  else
52
50
  value
@@ -57,6 +57,7 @@ module ActiveRecord
57
57
 
58
58
  def dump(stream)
59
59
  header(stream)
60
+ schemas(stream)
60
61
  extensions(stream)
61
62
  types(stream)
62
63
  tables(stream)
@@ -119,6 +120,10 @@ module ActiveRecord
119
120
  def types(stream)
120
121
  end
121
122
 
123
+ # schemas are only supported by PostgreSQL
124
+ def schemas(stream)
125
+ end
126
+
122
127
  def tables(stream)
123
128
  sorted_tables = @connection.tables.sort
124
129
 
@@ -188,7 +193,7 @@ module ActiveRecord
188
193
  indexes_in_create(table, tbl)
189
194
  check_constraints_in_create(table, tbl) if @connection.supports_check_constraints?
190
195
  exclusion_constraints_in_create(table, tbl) if @connection.supports_exclusion_constraints?
191
- unique_keys_in_create(table, tbl) if @connection.supports_unique_keys?
196
+ unique_constraints_in_create(table, tbl) if @connection.supports_unique_constraints?
192
197
 
193
198
  tbl.puts " end"
194
199
  tbl.puts
@@ -224,10 +229,10 @@ module ActiveRecord
224
229
  indexes = indexes.reject { |index| exclusion_constraint_names.include?(index.name) }
225
230
  end
226
231
 
227
- if @connection.supports_unique_keys? && (unique_keys = @connection.unique_keys(table)).any?
228
- unique_key_names = unique_keys.collect(&:name)
232
+ if @connection.supports_unique_constraints? && (unique_constraints = @connection.unique_constraints(table)).any?
233
+ unique_constraint_names = unique_constraints.collect(&:name)
229
234
 
230
- indexes = indexes.reject { |index| unique_key_names.include?(index.name) }
235
+ indexes = indexes.reject { |index| unique_constraint_names.include?(index.name) }
231
236
  end
232
237
 
233
238
  index_statements = indexes.map do |index|
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.1.0.beta1
4
+ version: 7.1.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-13 00:00:00.000000000 Z
11
+ date: 2023-09-27 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.1.0.beta1
19
+ version: 7.1.0.rc1
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.1.0.beta1
26
+ version: 7.1.0.rc1
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.1.0.beta1
33
+ version: 7.1.0.rc1
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.1.0.beta1
40
+ version: 7.1.0.rc1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: timeout
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -469,10 +469,10 @@ licenses:
469
469
  - MIT
470
470
  metadata:
471
471
  bug_tracker_uri: https://github.com/rails/rails/issues
472
- changelog_uri: https://github.com/rails/rails/blob/v7.1.0.beta1/activerecord/CHANGELOG.md
473
- documentation_uri: https://api.rubyonrails.org/v7.1.0.beta1/
472
+ changelog_uri: https://github.com/rails/rails/blob/v7.1.0.rc1/activerecord/CHANGELOG.md
473
+ documentation_uri: https://api.rubyonrails.org/v7.1.0.rc1/
474
474
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
475
- source_code_uri: https://github.com/rails/rails/tree/v7.1.0.beta1/activerecord
475
+ source_code_uri: https://github.com/rails/rails/tree/v7.1.0.rc1/activerecord
476
476
  rubygems_mfa_required: 'true'
477
477
  post_install_message:
478
478
  rdoc_options: