activerecord 7.1.3 → 7.1.5

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +319 -0
  3. data/lib/active_record/associations/belongs_to_association.rb +4 -4
  4. data/lib/active_record/associations/collection_association.rb +4 -4
  5. data/lib/active_record/associations/has_many_association.rb +2 -2
  6. data/lib/active_record/associations/has_one_association.rb +2 -2
  7. data/lib/active_record/associations/join_dependency/join_association.rb +3 -2
  8. data/lib/active_record/associations/join_dependency.rb +10 -12
  9. data/lib/active_record/associations.rb +6 -0
  10. data/lib/active_record/attribute_methods/dirty.rb +2 -2
  11. data/lib/active_record/attribute_methods/read.rb +3 -3
  12. data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -0
  13. data/lib/active_record/attribute_methods/write.rb +3 -3
  14. data/lib/active_record/attribute_methods.rb +46 -6
  15. data/lib/active_record/autosave_association.rb +5 -2
  16. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +8 -1
  17. data/lib/active_record/connection_adapters/abstract/database_statements.rb +1 -1
  18. data/lib/active_record/connection_adapters/abstract/query_cache.rb +1 -1
  19. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +8 -4
  20. data/lib/active_record/connection_adapters/abstract_adapter.rb +14 -15
  21. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +37 -13
  22. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +2 -1
  23. data/lib/active_record/connection_adapters/mysql2_adapter.rb +16 -10
  24. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
  25. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +3 -1
  26. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +2 -2
  27. data/lib/active_record/connection_adapters/trilogy_adapter.rb +16 -20
  28. data/lib/active_record/core.rb +8 -3
  29. data/lib/active_record/counter_cache.rb +7 -3
  30. data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -1
  31. data/lib/active_record/database_configurations/hash_config.rb +6 -2
  32. data/lib/active_record/delegated_type.rb +6 -6
  33. data/lib/active_record/destroy_association_async_job.rb +1 -1
  34. data/lib/active_record/encryption/encrypted_attribute_type.rb +2 -2
  35. data/lib/active_record/encryption/scheme.rb +8 -4
  36. data/lib/active_record/encryption.rb +2 -0
  37. data/lib/active_record/enum.rb +1 -1
  38. data/lib/active_record/future_result.rb +9 -0
  39. data/lib/active_record/gem_version.rb +1 -1
  40. data/lib/active_record/locking/optimistic.rb +1 -1
  41. data/lib/active_record/marshalling.rb +4 -1
  42. data/lib/active_record/message_pack.rb +1 -1
  43. data/lib/active_record/migration/compatibility.rb +6 -0
  44. data/lib/active_record/model_schema.rb +7 -2
  45. data/lib/active_record/nested_attributes.rb +13 -2
  46. data/lib/active_record/persistence.rb +2 -2
  47. data/lib/active_record/query_cache.rb +1 -1
  48. data/lib/active_record/query_logs_formatter.rb +1 -1
  49. data/lib/active_record/railtie.rb +14 -14
  50. data/lib/active_record/railties/databases.rake +2 -2
  51. data/lib/active_record/reflection.rb +8 -2
  52. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +6 -1
  53. data/lib/active_record/relation/query_methods.rb +21 -7
  54. data/lib/active_record/relation.rb +13 -3
  55. data/lib/active_record/result.rb +1 -1
  56. data/lib/active_record/tasks/database_tasks.rb +30 -8
  57. data/lib/active_record/test_fixtures.rb +1 -0
  58. data/lib/active_record/timestamp.rb +3 -1
  59. data/lib/active_record.rb +2 -2
  60. data/lib/arel/tree_manager.rb +5 -1
  61. data/lib/arel/visitors/to_sql.rb +2 -1
  62. metadata +13 -13
@@ -80,6 +80,11 @@ module ActiveRecord
80
80
  super
81
81
  end
82
82
 
83
+ def references(*args, **options)
84
+ options[:_skip_validate_options] = true
85
+ super
86
+ end
87
+
83
88
  private
84
89
  def raise_on_if_exist_options(options)
85
90
  end
@@ -112,6 +117,7 @@ module ActiveRecord
112
117
 
113
118
  def rename_table(table_name, new_name, **options)
114
119
  options[:_uses_legacy_table_name] = true
120
+ options[:_uses_legacy_index_name] = true
115
121
  super
116
122
  end
117
123
 
@@ -432,8 +432,12 @@ module ActiveRecord
432
432
  end
433
433
 
434
434
  def _returning_columns_for_insert # :nodoc:
435
- @_returning_columns_for_insert ||= columns.filter_map do |c|
436
- c.name if connection.return_value_after_insert?(c)
435
+ @_returning_columns_for_insert ||= begin
436
+ auto_populated_columns = columns.filter_map do |c|
437
+ c.name if connection.return_value_after_insert?(c)
438
+ end
439
+
440
+ auto_populated_columns.empty? ? Array(primary_key) : auto_populated_columns
437
441
  end
438
442
  end
439
443
 
@@ -629,6 +633,7 @@ module ActiveRecord
629
633
  )
630
634
  alias_attribute :id_value, :id if name == "id"
631
635
  end
636
+ _default_attributes # Precompute to cache DB-dependent attribute types
632
637
  end
633
638
 
634
639
  # Guesses the table name, but does not decorate it with prefix and suffix information.
@@ -519,12 +519,12 @@ module ActiveRecord
519
519
  unless reject_new_record?(association_name, attributes)
520
520
  association.reader.build(attributes.except(*UNASSIGNABLE_KEYS))
521
521
  end
522
- elsif existing_record = existing_records.detect { |record| record.id.to_s == attributes["id"].to_s }
522
+ elsif existing_record = find_record_by_id(existing_records, attributes["id"])
523
523
  unless call_reject_if(association_name, attributes)
524
524
  # Make sure we are operating on the actual object which is in the association's
525
525
  # proxy_target array (either by finding it, or adding it if not found)
526
526
  # Take into account that the proxy_target may have changed due to callbacks
527
- target_record = association.target.detect { |record| record.id.to_s == attributes["id"].to_s }
527
+ target_record = find_record_by_id(association.target, attributes["id"])
528
528
  if target_record
529
529
  existing_record = target_record
530
530
  else
@@ -612,5 +612,16 @@ module ActiveRecord
612
612
  raise RecordNotFound.new("Couldn't find #{model} with ID=#{record_id} for #{self.class.name} with ID=#{id}",
613
613
  model, "id", record_id)
614
614
  end
615
+
616
+ def find_record_by_id(records, id)
617
+ return if records.empty?
618
+
619
+ if records.first.class.composite_primary_key?
620
+ id = Array(id).map(&:to_s)
621
+ records.find { |record| Array(record.id).map(&:to_s) == id }
622
+ else
623
+ records.find { |record| record.id.to_s == id.to_s }
624
+ end
625
+ end
615
626
  end
616
627
  end
@@ -456,7 +456,7 @@ module ActiveRecord
456
456
  end
457
457
 
458
458
  # Accepts a list of attribute names to be used in the WHERE clause
459
- # of SELECT / UPDATE / DELETE queries and in the ORDER BY clause for `#first` and `#last` finder methods.
459
+ # of SELECT / UPDATE / DELETE queries and in the ORDER BY clause for +#first+ and +#last+ finder methods.
460
460
  #
461
461
  # class Developer < ActiveRecord::Base
462
462
  # query_constraints :company_id, :id
@@ -469,7 +469,7 @@ module ActiveRecord
469
469
  # developer.update!(name: "Nikita")
470
470
  # # UPDATE "developers" SET "name" = 'Nikita' WHERE "developers"."company_id" = 1 AND "developers"."id" = 1
471
471
  #
472
- # It is possible to update attribute used in the query_by clause:
472
+ # # It is possible to update an attribute used in the query_constraints clause:
473
473
  # developer.update!(company_id: 2)
474
474
  # # UPDATE "developers" SET "company_id" = 2 WHERE "developers"."company_id" = 1 AND "developers"."id" = 1
475
475
  #
@@ -30,7 +30,7 @@ module ActiveRecord
30
30
  end
31
31
 
32
32
  def self.complete(pools)
33
- pools.each { |pool| pool.disable_query_cache! }
33
+ pools.each { |pool| pool.disable_query_cache! unless pool.discarded? }
34
34
 
35
35
  ActiveRecord::Base.connection_handler.each_connection_pool do |pool|
36
36
  pool.release_connection if pool.active_connection? && !pool.connection.transaction_open?
@@ -28,7 +28,7 @@ module ActiveRecord
28
28
  end
29
29
 
30
30
  def format(pairs)
31
- pairs.sort_by!(&:first)
31
+ pairs.sort_by! { |pair| pair.first.to_s }
32
32
  super
33
33
  end
34
34
 
@@ -146,6 +146,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
146
146
  config.after_initialize do |app|
147
147
  ActiveSupport.on_load(:active_record) do
148
148
  db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).first
149
+ next if db_config.nil?
149
150
 
150
151
  filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(
151
152
  db_config.name,
@@ -261,8 +262,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
261
262
  end
262
263
 
263
264
  ActiveSupport.on_load(:active_record) do
264
- # Configs used in other initializers
265
- configs = configs.except(
265
+ configs_used_in_other_initializers = configs.except(
266
266
  :migration_error,
267
267
  :database_selector,
268
268
  :database_resolver,
@@ -279,7 +279,7 @@ To keep using the current cache store, you can turn off cache versioning entirel
279
279
  :use_schema_cache_dump
280
280
  )
281
281
 
282
- configs.each do |k, v|
282
+ configs_used_in_other_initializers.each do |k, v|
283
283
  next if k == :encryption
284
284
  setter = "#{k}="
285
285
  # Some existing initializers might rely on Active Record configuration
@@ -377,23 +377,23 @@ To keep using the current cache store, you can turn off cache versioning entirel
377
377
  end
378
378
 
379
379
  initializer "active_record_encryption.configuration" do |app|
380
- auto_filtered_parameters = ActiveRecord::Encryption::AutoFilteredParameters.new(app)
381
-
382
- config.after_initialize do |app|
383
- ActiveRecord::Encryption.configure \
380
+ ActiveSupport.on_load(:active_record_encryption) do
381
+ ActiveRecord::Encryption.configure(
384
382
  primary_key: app.credentials.dig(:active_record_encryption, :primary_key),
385
383
  deterministic_key: app.credentials.dig(:active_record_encryption, :deterministic_key),
386
384
  key_derivation_salt: app.credentials.dig(:active_record_encryption, :key_derivation_salt),
387
- **config.active_record.encryption
385
+ **app.config.active_record.encryption
386
+ )
388
387
 
388
+ auto_filtered_parameters = ActiveRecord::Encryption::AutoFilteredParameters.new(app)
389
389
  auto_filtered_parameters.enable if ActiveRecord::Encryption.config.add_to_filter_parameters
390
+ end
390
391
 
391
- ActiveSupport.on_load(:active_record) do
392
- # Support extended queries for deterministic attributes and validations
393
- if ActiveRecord::Encryption.config.extend_queries
394
- ActiveRecord::Encryption::ExtendedDeterministicQueries.install_support
395
- ActiveRecord::Encryption::ExtendedDeterministicUniquenessValidator.install_support
396
- end
392
+ ActiveSupport.on_load(:active_record) do
393
+ # Support extended queries for deterministic attributes and validations
394
+ if ActiveRecord::Encryption.config.extend_queries
395
+ ActiveRecord::Encryption::ExtendedDeterministicQueries.install_support
396
+ ActiveRecord::Encryption::ExtendedDeterministicUniquenessValidator.install_support
397
397
  end
398
398
  end
399
399
 
@@ -89,10 +89,10 @@ db_namespace = namespace :db do
89
89
  task migrate: :load_config do
90
90
  db_configs = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env)
91
91
 
92
- if db_configs.size == 1
92
+ if db_configs.size == 1 && db_configs.first.primary?
93
93
  ActiveRecord::Tasks::DatabaseTasks.migrate
94
94
  else
95
- mapped_versions = ActiveRecord::Tasks::DatabaseTasks.db_configs_with_versions(db_configs)
95
+ mapped_versions = ActiveRecord::Tasks::DatabaseTasks.db_configs_with_versions
96
96
 
97
97
  mapped_versions.sort.each do |version, db_configs|
98
98
  db_configs.each do |db_config|
@@ -786,7 +786,7 @@ module ActiveRecord
786
786
  primary_query_constraints = active_record.query_constraints_list
787
787
  owner_pk = active_record.primary_key
788
788
 
789
- if primary_query_constraints.size != 2
789
+ if primary_query_constraints.size > 2
790
790
  raise ArgumentError, <<~MSG.squish
791
791
  The query constraints list on the `#{active_record}` model has more than 2
792
792
  attributes. Active Record is unable to derive the query constraints
@@ -804,6 +804,8 @@ module ActiveRecord
804
804
  MSG
805
805
  end
806
806
 
807
+ return foreign_key if primary_query_constraints.include?(foreign_key)
808
+
807
809
  first_key, last_key = primary_query_constraints
808
810
 
809
811
  if first_key == owner_pk
@@ -869,7 +871,11 @@ module ActiveRecord
869
871
  # klass option is necessary to support loading polymorphic associations
870
872
  def association_primary_key(klass = nil)
871
873
  if primary_key = options[:primary_key]
872
- @association_primary_key ||= -primary_key.to_s
874
+ @association_primary_key ||= if primary_key.is_a?(Array)
875
+ primary_key.map { |pk| pk.to_s.freeze }.freeze
876
+ else
877
+ -primary_key.to_s
878
+ end
873
879
  elsif (klass || self.klass).has_query_constraints? || options[:query_constraints]
874
880
  (klass || self.klass).composite_query_constraints_list
875
881
  elsif (klass || self.klass).composite_primary_key?
@@ -43,7 +43,12 @@ module ActiveRecord
43
43
 
44
44
  def convert_to_id(value)
45
45
  if value.is_a?(Base)
46
- value._read_attribute(primary_key(value))
46
+ primary_key = primary_key(value)
47
+ if primary_key.is_a?(Array)
48
+ primary_key.map { |column| value._read_attribute(column) }
49
+ else
50
+ value._read_attribute(primary_key)
51
+ end
47
52
  elsif value.is_a?(Relation)
48
53
  value.select(primary_key(value))
49
54
  else
@@ -1909,18 +1909,32 @@ module ActiveRecord
1909
1909
  end
1910
1910
 
1911
1911
  def column_references(order_args)
1912
- references = order_args.flat_map do |arg|
1912
+ order_args.flat_map do |arg|
1913
1913
  case arg
1914
1914
  when String, Symbol
1915
- arg
1915
+ extract_table_name_from(arg)
1916
1916
  when Hash
1917
- arg.keys.map do |key|
1918
- key if key.is_a?(String) || key.is_a?(Symbol)
1917
+ arg
1918
+ .map do |key, value|
1919
+ case value
1920
+ when Hash
1921
+ key.to_s
1922
+ else
1923
+ extract_table_name_from(key) if key.is_a?(String) || key.is_a?(Symbol)
1924
+ end
1925
+ end
1926
+ when Arel::Attribute
1927
+ arg.relation.name
1928
+ when Arel::Nodes::Ordering
1929
+ if arg.expr.is_a?(Arel::Attribute)
1930
+ arg.expr.relation.name
1919
1931
  end
1920
1932
  end
1921
- end
1922
- references.map! { |arg| arg =~ /^\W?(\w+)\W?\./ && $1 }.compact!
1923
- references
1933
+ end.compact
1934
+ end
1935
+
1936
+ def extract_table_name_from(string)
1937
+ string.match(/^\W?(\w+)\W?\./) && $1
1924
1938
  end
1925
1939
 
1926
1940
  def order_column(field)
@@ -526,7 +526,12 @@ module ActiveRecord
526
526
 
527
527
  group_values_arel_columns = arel_columns(group_values.uniq)
528
528
  having_clause_ast = having_clause.ast unless having_clause.empty?
529
- stmt = arel.compile_update(values, table[primary_key], having_clause_ast, group_values_arel_columns)
529
+ key = if klass.composite_primary_key?
530
+ primary_key.map { |pk| table[pk] }
531
+ else
532
+ table[primary_key]
533
+ end
534
+ stmt = arel.compile_update(values, key, having_clause_ast, group_values_arel_columns)
530
535
  klass.connection.update(stmt, "#{klass} Update All").tap { reset }
531
536
  end
532
537
 
@@ -659,7 +664,12 @@ module ActiveRecord
659
664
 
660
665
  group_values_arel_columns = arel_columns(group_values.uniq)
661
666
  having_clause_ast = having_clause.ast unless having_clause.empty?
662
- stmt = arel.compile_delete(table[primary_key], having_clause_ast, group_values_arel_columns)
667
+ key = if klass.composite_primary_key?
668
+ primary_key.map { |pk| table[pk] }
669
+ else
670
+ table[primary_key]
671
+ end
672
+ stmt = arel.compile_delete(key, having_clause_ast, group_values_arel_columns)
663
673
 
664
674
  klass.connection.delete(stmt, "#{klass} Delete All").tap { reset }
665
675
  end
@@ -975,7 +985,7 @@ module ActiveRecord
975
985
  def exec_main_query(async: false)
976
986
  if @none
977
987
  if async
978
- return FutureResult::Complete.new([])
988
+ return FutureResult.wrap([])
979
989
  else
980
990
  return []
981
991
  end
@@ -195,7 +195,7 @@ module ActiveRecord
195
195
  EMPTY = new([].freeze, [].freeze, {}.freeze).freeze
196
196
  private_constant :EMPTY
197
197
 
198
- EMPTY_ASYNC = FutureResult::Complete.new(EMPTY).freeze
198
+ EMPTY_ASYNC = FutureResult.wrap(EMPTY).freeze
199
199
  private_constant :EMPTY_ASYNC
200
200
  end
201
201
  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
@@ -192,9 +193,27 @@ module ActiveRecord
192
193
 
193
194
  seed = true
194
195
  end
196
+ end
197
+ end
198
+
199
+ each_current_environment(env) do |environment|
200
+ db_configs_with_versions(environment).sort.each do |version, db_configs|
201
+ dump_db_configs |= db_configs
202
+
203
+ db_configs.each do |db_config|
204
+ with_temporary_pool(db_config) do
205
+ migrate(version)
206
+ end
207
+ end
208
+ end
209
+ end
195
210
 
196
- migrate
197
- dump_schema(db_config) if ActiveRecord.dump_schema_after_migration
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
198
217
  end
199
218
  end
200
219
 
@@ -255,10 +274,10 @@ module ActiveRecord
255
274
  Migration.verbose = verbose_was
256
275
  end
257
276
 
258
- def db_configs_with_versions(db_configs) # :nodoc:
277
+ def db_configs_with_versions(environment = env) # :nodoc:
259
278
  db_configs_with_versions = Hash.new { |h, k| h[k] = [] }
260
279
 
261
- with_temporary_connection_for_each do |conn|
280
+ with_temporary_connection_for_each(env: environment) do |conn|
262
281
  db_config = conn.pool.db_config
263
282
  versions_to_run = conn.migration_context.pending_migration_versions
264
283
  target_version = ActiveRecord::Tasks::DatabaseTasks.target_version
@@ -552,10 +571,7 @@ module ActiveRecord
552
571
  end
553
572
 
554
573
  def each_current_configuration(environment, name = nil)
555
- environments = [environment]
556
- environments << "test" if environment == "development" && !ENV["SKIP_TEST_DATABASE"] && !ENV["DATABASE_URL"]
557
-
558
- environments.each do |env|
574
+ each_current_environment(environment) do |env|
559
575
  configs_for(env_name: env).each do |db_config|
560
576
  next if name && name != db_config.name
561
577
 
@@ -564,6 +580,12 @@ module ActiveRecord
564
580
  end
565
581
  end
566
582
 
583
+ def each_current_environment(environment, &block)
584
+ environments = [environment]
585
+ environments << "test" if environment == "development" && !ENV["SKIP_TEST_DATABASE"] && !ENV["DATABASE_URL"]
586
+ environments.each(&block)
587
+ end
588
+
567
589
  def each_local_configuration
568
590
  configs_for.each do |db_config|
569
591
  next unless db_config.database
@@ -13,6 +13,7 @@ module ActiveRecord
13
13
 
14
14
  def after_teardown # :nodoc:
15
15
  super
16
+ ensure
16
17
  teardown_fixtures
17
18
  end
18
19
 
@@ -54,8 +54,10 @@ module ActiveRecord
54
54
 
55
55
  module ClassMethods # :nodoc:
56
56
  def touch_attributes_with_time(*names, time: nil)
57
+ names = names.map(&:to_s)
58
+ names = names.map { |name| attribute_aliases[name] || name }
57
59
  attribute_names = timestamp_attributes_for_update_in_model
58
- attribute_names |= names.map(&:to_s)
60
+ attribute_names |= names
59
61
  attribute_names.index_with(time || current_time_from_proper_timezone)
60
62
  end
61
63
 
data/lib/active_record.rb CHANGED
@@ -34,7 +34,7 @@ require "active_record/deprecator"
34
34
  require "active_model/attribute_set"
35
35
  require "active_record/errors"
36
36
 
37
- # :include: activerecord/README.rdoc
37
+ # :include: ../README.rdoc
38
38
  module ActiveRecord
39
39
  extend ActiveSupport::Autoload
40
40
 
@@ -277,7 +277,7 @@ module ActiveRecord
277
277
  # with the global thread pool async query executor.
278
278
  def self.global_executor_concurrency=(global_executor_concurrency)
279
279
  if self.async_query_executor.nil? || self.async_query_executor == :multi_thread_pool
280
- raise ArgumentError, "`global_executor_concurrency` cannot be set when using the executor is nil or set to multi_thead_pool. For multiple thread pools, please set the concurrency in your database configuration."
280
+ raise ArgumentError, "`global_executor_concurrency` cannot be set when the executor is nil or set to `:multi_thread_pool`. For multiple thread pools, please set the concurrency in your database configuration."
281
281
  end
282
282
 
283
283
  @global_executor_concurrency = global_executor_concurrency
@@ -21,7 +21,11 @@ module Arel # :nodoc: all
21
21
  end
22
22
 
23
23
  def key=(key)
24
- @ast.key = Nodes.build_quoted(key)
24
+ @ast.key = if key.is_a?(Array)
25
+ key.map { |k| Nodes.build_quoted(k) }
26
+ else
27
+ Nodes.build_quoted(key)
28
+ end
25
29
  end
26
30
 
27
31
  def key
@@ -930,7 +930,8 @@ module Arel # :nodoc: all
930
930
  stmt.limit = nil
931
931
  stmt.offset = nil
932
932
  stmt.orders = []
933
- stmt.wheres = [Nodes::In.new(o.key, [build_subselect(o.key, o)])]
933
+ columns = Arel::Nodes::Grouping.new(o.key)
934
+ stmt.wheres = [Nodes::In.new(columns, [build_subselect(o.key, o)])]
934
935
  stmt.relation = o.relation.left if has_join_sources?(o)
935
936
  stmt.groups = o.groups unless o.groups.empty?
936
937
  stmt.havings = o.havings unless o.havings.empty?
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.3
4
+ version: 7.1.5
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-01-16 00:00:00.000000000 Z
11
+ date: 2024-10-31 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.3
19
+ version: 7.1.5
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.3
26
+ version: 7.1.5
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.3
33
+ version: 7.1.5
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.3
40
+ version: 7.1.5
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: timeout
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -470,12 +470,12 @@ licenses:
470
470
  - MIT
471
471
  metadata:
472
472
  bug_tracker_uri: https://github.com/rails/rails/issues
473
- changelog_uri: https://github.com/rails/rails/blob/v7.1.3/activerecord/CHANGELOG.md
474
- documentation_uri: https://api.rubyonrails.org/v7.1.3/
473
+ changelog_uri: https://github.com/rails/rails/blob/v7.1.5/activerecord/CHANGELOG.md
474
+ documentation_uri: https://api.rubyonrails.org/v7.1.5/
475
475
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
476
- source_code_uri: https://github.com/rails/rails/tree/v7.1.3/activerecord
476
+ source_code_uri: https://github.com/rails/rails/tree/v7.1.5/activerecord
477
477
  rubygems_mfa_required: 'true'
478
- post_install_message:
478
+ post_install_message:
479
479
  rdoc_options:
480
480
  - "--main"
481
481
  - README.rdoc
@@ -492,8 +492,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
492
492
  - !ruby/object:Gem::Version
493
493
  version: '0'
494
494
  requirements: []
495
- rubygems_version: 3.4.18
496
- signing_key:
495
+ rubygems_version: 3.5.16
496
+ signing_key:
497
497
  specification_version: 4
498
498
  summary: Object-relational mapper framework (part of Rails).
499
499
  test_files: []