activerecord 7.0.0 → 7.0.2.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +175 -0
  3. data/MIT-LICENSE +1 -1
  4. data/lib/active_record/associations.rb +29 -8
  5. data/lib/active_record/attribute_methods.rb +1 -1
  6. data/lib/active_record/autosave_association.rb +2 -2
  7. data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -1
  8. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +4 -4
  9. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
  10. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +9 -4
  11. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +1 -1
  12. data/lib/active_record/connection_adapters/mysql/database_statements.rb +1 -1
  13. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +7 -1
  14. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +1 -0
  15. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +2 -0
  16. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +8 -3
  17. data/lib/active_record/connection_adapters/postgresql_adapter.rb +2 -2
  18. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +13 -0
  19. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +12 -12
  20. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +28 -0
  21. data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -0
  22. data/lib/active_record/database_configurations.rb +1 -1
  23. data/lib/active_record/encryption/configurable.rb +2 -2
  24. data/lib/active_record/encryption/extended_deterministic_queries.rb +28 -28
  25. data/lib/active_record/fixtures.rb +1 -1
  26. data/lib/active_record/gem_version.rb +2 -2
  27. data/lib/active_record/integration.rb +2 -2
  28. data/lib/active_record/migration/compatibility.rb +24 -2
  29. data/lib/active_record/migration.rb +1 -1
  30. data/lib/active_record/railtie.rb +2 -2
  31. data/lib/active_record/reflection.rb +1 -1
  32. data/lib/active_record/relation/calculations.rb +3 -2
  33. data/lib/active_record/relation/delegation.rb +1 -1
  34. data/lib/active_record/relation/query_methods.rb +19 -5
  35. data/lib/active_record/relation.rb +16 -1
  36. data/lib/active_record/schema.rb +38 -23
  37. data/lib/active_record/schema_dumper.rb +15 -16
  38. data/lib/active_record/tasks/database_tasks.rb +6 -2
  39. data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -1
  40. data/lib/active_record.rb +1 -1
  41. metadata +13 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ebfa716fe92ae11e586b89a89661980f107b3501dcbc64be179a191645046e2a
4
- data.tar.gz: 0eb8e39ca0252342714ad4791d5a17127697a7047b4ed2c7d48a867774f8470b
3
+ metadata.gz: 8c33dacf42d19439217c8ca1869c9760c3aae71ca9b4b2155fa58729c802e4ba
4
+ data.tar.gz: c4444cddcab6a46fd9c38b9c03f58ce785d44fbb564a3985676bcec8ad99e98c
5
5
  SHA512:
6
- metadata.gz: 74365d846a7f543a82e61c3784aad30dd1de0e2a43e09ed4459a4b7b0fe9a14839a53122e12536c63d3bdcb638391390b83e6ffa4eb6a09f8713e1986674cda9
7
- data.tar.gz: a1379b0d243f97f6827df6ff2af3a7936164ad57ad60ded0aac71aeb45def6d7cee19571de89f8d93eeeaabfc6d193b9695879b8dac5c9f7d473e85617d15bea
6
+ metadata.gz: 6e8ada99b5f4ab64565ed58f6526aa1ffb40605e0769ccc344f896fc934cd1519841e8fea9e753cfd4d3d7f96490dc7a668c101c0d4ef178bb23e6c8d5e6d884
7
+ data.tar.gz: 771f2198ae227ffb4f5ae9e47e1d3ccf6201f4b9b40c79a03ea662d46d426f8c7d13855c7017c5f99b5748fafb1c07026fa965e1a87b1f1d2271ff4a3901c40e
data/CHANGELOG.md CHANGED
@@ -1,3 +1,176 @@
1
+ ## Rails 7.0.2.2 (February 11, 2022) ##
2
+
3
+ * No changes.
4
+
5
+
6
+ ## Rails 7.0.2.1 (February 11, 2022) ##
7
+
8
+ * No changes.
9
+
10
+
11
+ ## Rails 7.0.2 (February 08, 2022) ##
12
+
13
+ * Fix `PG.connect` keyword arguments deprecation warning on ruby 2.7.
14
+
15
+ *Nikita Vasilevsky*
16
+
17
+ * Fix the ability to exclude encryption params from being autofiltered.
18
+
19
+ *Mark Gangl*
20
+
21
+ * Dump the precision for datetime columns following the new defaults.
22
+
23
+ *Rafael Mendonça França*
24
+
25
+ * Make sure encrypted attributes are not being filtered twice.
26
+
27
+ *Nikita Vasilevsky*
28
+
29
+ * Dump the database schema containing the current Rails version.
30
+
31
+ Since https://github.com/rails/rails/pull/42297, Rails now generate datetime columns
32
+ with a default precision of 6. This means that users upgrading to Rails 7.0 from 6.1,
33
+ when loading the database schema, would get the new precision value, which would not match
34
+ the production schema.
35
+
36
+ To avoid this the schema dumper will generate the new format which will include the Rails
37
+ version and will look like this:
38
+
39
+ ```
40
+ ActiveRecord::Schema[7.0].define
41
+ ```
42
+
43
+ When upgrading from Rails 6.1 to Rails 7.0, you can run the `rails app:update` task that will
44
+ set the current schema version to 6.1.
45
+
46
+ *Rafael Mendonça França*
47
+
48
+ * Fix parsing expression for PostgreSQL generated column.
49
+
50
+ *fatkodima*
51
+
52
+ * Fix `Mysql2::Error: Commands out of sync; you can't run this command now`
53
+ when bulk-inserting fixtures that exceed `max_allowed_packet` configuration.
54
+
55
+ *Nikita Vasilevsky*
56
+
57
+ * Fix error when saving an association with a relation named `record`.
58
+
59
+ *Dorian Marié*
60
+
61
+ * Fix `MySQL::SchemaDumper` behavior about datetime precision value.
62
+
63
+ *y0t4*
64
+
65
+ * Improve associated with no reflection error.
66
+
67
+ *Nikolai*
68
+
69
+ * Fix PG.connect keyword arguments deprecation warning on ruby 2.7.
70
+
71
+ Fixes #44307.
72
+
73
+ *Nikita Vasilevsky*
74
+
75
+ * Fix passing options to `check_constraint` from `change_table`.
76
+
77
+ *Frederick Cheung*
78
+
79
+
80
+ ## Rails 7.0.1 (January 06, 2022) ##
81
+
82
+
83
+ * Change `QueryMethods#in_order_of` to drop records not listed in values.
84
+
85
+ `in_order_of` now filters down to the values provided, to match the behavior of the `Enumerable` version.
86
+
87
+ *Kevin Newton*
88
+
89
+ * Allow named expression indexes to be revertible.
90
+
91
+ Previously, the following code would raise an error in a reversible migration executed while rolling back, due to the index name not being used in the index removal.
92
+
93
+ ```ruby
94
+ add_index(:settings, "(data->'property')", using: :gin, name: :index_settings_data_property)
95
+ ```
96
+
97
+ Fixes #43331.
98
+
99
+ *Oliver Günther*
100
+
101
+ * Better error messages when association name is invalid in the argument of `ActiveRecord::QueryMethods::WhereChain#missing`.
102
+
103
+ *ykpythemind*
104
+
105
+ * Fix ordered migrations for single db in multi db environment.
106
+
107
+ *Himanshu*
108
+
109
+ * Extract `on update CURRENT_TIMESTAMP` for mysql2 adapter.
110
+
111
+ *Kazuhiro Masuda*
112
+
113
+ * Fix incorrect argument in PostgreSQL structure dump tasks.
114
+
115
+ Updating the `--no-comment` argument added in Rails 7 to the correct `--no-comments` argument.
116
+
117
+ *Alex Dent*
118
+
119
+ * Fix schema dumping column default SQL values for sqlite3.
120
+
121
+ *fatkodima*
122
+
123
+ * Correctly parse complex check constraint expressions for PostgreSQL.
124
+
125
+ *fatkodima*
126
+
127
+ * Fix `timestamptz` attributes on PostgreSQL handle blank inputs.
128
+
129
+ *Alex Ghiculescu*
130
+
131
+ * Fix migration compatibility to create SQLite references/belongs_to column as integer when migration version is 6.0.
132
+
133
+ Reference/belongs_to in migrations with version 6.0 were creating columns as
134
+ bigint instead of integer for the SQLite Adapter.
135
+
136
+ *Marcelo Lauxen*
137
+
138
+ * Fix joining through a polymorphic association.
139
+
140
+ *Alexandre Ruban*
141
+
142
+ * Fix `QueryMethods#in_order_of` to handle empty order list.
143
+
144
+ ```ruby
145
+ Post.in_order_of(:id, []).to_a
146
+ ```
147
+
148
+ Also more explicitly set the column as secondary order, so that any other
149
+ value is still ordered.
150
+
151
+ *Jean Boussier*
152
+
153
+ * Fix `rails dbconsole` for 3-tier config.
154
+
155
+ *Eileen M. Uchitelle*
156
+
157
+ * Fix quoting of column aliases generated by calculation methods.
158
+
159
+ Since the alias is derived from the table name, we can't assume the result
160
+ is a valid identifier.
161
+
162
+ ```ruby
163
+ class Test < ActiveRecord::Base
164
+ self.table_name = '1abc'
165
+ end
166
+ Test.group(:id).count
167
+ # syntax error at or near "1" (ActiveRecord::StatementInvalid)
168
+ # LINE 1: SELECT COUNT(*) AS count_all, "1abc"."id" AS 1abc_id FROM "1...
169
+ ```
170
+
171
+ *Jean Boussier*
172
+
173
+
1
174
  ## Rails 7.0.0 (December 15, 2021) ##
2
175
 
3
176
  * Better handle SQL queries with invalid encoding.
@@ -20,6 +193,7 @@
20
193
 
21
194
  *Eileen M. Uchitelle*
22
195
 
196
+
23
197
  ## Rails 7.0.0.rc3 (December 14, 2021) ##
24
198
 
25
199
  * No changes.
@@ -29,6 +203,7 @@
29
203
 
30
204
  * No changes.
31
205
 
206
+
32
207
  ## Rails 7.0.0.rc1 (December 06, 2021) ##
33
208
 
34
209
  * Remove deprecated `ActiveRecord::DatabaseConfigurations::DatabaseConfig#spec_name`.
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2004-2021 David Heinemeier Hansson
1
+ Copyright (c) 2004-2022 David Heinemeier Hansson
2
2
 
3
3
  Arel originally copyright (c) 2007-2016 Nick Kallen, Bryan Helmkamp, Emilio Tagua, Aaron Patterson
4
4
 
@@ -290,6 +290,7 @@ module ActiveRecord
290
290
  def self.eager_load!
291
291
  super
292
292
  Preloader.eager_load!
293
+ JoinDependency.eager_load!
293
294
  end
294
295
 
295
296
  # Returns the association instance for the given name, instantiating it if it doesn't already exist
@@ -594,19 +595,27 @@ module ActiveRecord
594
595
  # you can also define callbacks that get triggered when you add an object to or remove an
595
596
  # object from an association collection.
596
597
  #
597
- # class Project
598
- # has_and_belongs_to_many :developers, after_add: :evaluate_velocity
598
+ # class Firm < ActiveRecord::Base
599
+ # has_many :clients,
600
+ # dependent: :destroy,
601
+ # after_add: :congratulate_client,
602
+ # after_remove: :log_after_remove
599
603
  #
600
- # def evaluate_velocity(developer)
601
- # ...
604
+ # def congratulate_client(record)
605
+ # # ...
606
+ # end
607
+ #
608
+ # def log_after_remove(record)
609
+ # # ...
602
610
  # end
603
- # end
604
611
  #
605
612
  # It's possible to stack callbacks by passing them as an array. Example:
606
613
  #
607
- # class Project
608
- # has_and_belongs_to_many :developers,
609
- # after_add: [:evaluate_velocity, Proc.new { |p, d| p.shipping_date = Time.now}]
614
+ # class Firm < ActiveRecord::Base
615
+ # has_many :clients,
616
+ # dependent: :destroy,
617
+ # after_add: [:congratulate_client, -> (firm, record) { firm.log << "after_adding#{record.id}" }],
618
+ # after_remove: :log_after_remove
610
619
  # end
611
620
  #
612
621
  # Possible callbacks are: +before_add+, +after_add+, +before_remove+ and +after_remove+.
@@ -617,6 +626,18 @@ module ActiveRecord
617
626
  # Similarly, if any of the +before_remove+ callbacks throw an exception, the object
618
627
  # will not be removed from the collection.
619
628
  #
629
+ # Note: To trigger remove callbacks, you must use +destroy+ / +destroy_all+ methods. For example:
630
+ #
631
+ # * <tt>firm.clients.destroy(client)</tt>
632
+ # * <tt>firm.clients.destroy(*clients)</tt>
633
+ # * <tt>firm.clients.destroy_all</tt>
634
+ #
635
+ # +delete+ / +delete_all+ methods like the following do *not* trigger remove callbacks:
636
+ #
637
+ # * <tt>firm.clients.delete(client)</tt>
638
+ # * <tt>firm.clients.delete(*clients)</tt>
639
+ # * <tt>firm.clients.delete_all</tt>
640
+ #
620
641
  # == Association extensions
621
642
  #
622
643
  # The proxy objects that control the access to associations can be extended through anonymous
@@ -413,7 +413,7 @@ module ActiveRecord
413
413
  inspected_value = if value.is_a?(String) && value.length > 50
414
414
  "#{value[0, 50]}...".inspect
415
415
  elsif value.is_a?(Date) || value.is_a?(Time)
416
- %("#{value.to_formatted_s(:inspect)}")
416
+ %("#{value.to_fs(:inspect)}")
417
417
  else
418
418
  value.inspect
419
419
  end
@@ -446,7 +446,7 @@ module ActiveRecord
446
446
  elsif autosave != false
447
447
  key = reflection.options[:primary_key] ? public_send(reflection.options[:primary_key]) : id
448
448
 
449
- if (autosave && record.changed_for_autosave?) || record_changed?(reflection, record, key)
449
+ if (autosave && record.changed_for_autosave?) || _record_changed?(reflection, record, key)
450
450
  unless reflection.through_reflection
451
451
  record[reflection.foreign_key] = key
452
452
  association.set_inverse_instance(record)
@@ -461,7 +461,7 @@ module ActiveRecord
461
461
  end
462
462
 
463
463
  # If the record is new or it has changed, returns true.
464
- def record_changed?(reflection, record, key)
464
+ def _record_changed?(reflection, record, key)
465
465
  record.new_record? ||
466
466
  association_foreign_key_changed?(reflection, record, key) ||
467
467
  record.will_save_change_to_attribute?(reflection.foreign_key)
@@ -128,7 +128,7 @@ module ActiveRecord
128
128
  end
129
129
  end
130
130
 
131
- result = value.to_formatted_s(:db)
131
+ result = value.to_fs(:db)
132
132
  if value.respond_to?(:usec) && value.usec > 0
133
133
  result << "." << sprintf("%06d", value.usec)
134
134
  else
@@ -810,8 +810,8 @@ module ActiveRecord
810
810
  # t.check_constraint("price > 0", name: "price_check")
811
811
  #
812
812
  # See {connection.add_check_constraint}[rdoc-ref:SchemaStatements#add_check_constraint]
813
- def check_constraint(*args)
814
- @base.add_check_constraint(name, *args)
813
+ def check_constraint(*args, **options)
814
+ @base.add_check_constraint(name, *args, **options)
815
815
  end
816
816
 
817
817
  # Removes the given check constraint from the table.
@@ -819,8 +819,8 @@ module ActiveRecord
819
819
  # t.remove_check_constraint(name: "price_check")
820
820
  #
821
821
  # See {connection.remove_check_constraint}[rdoc-ref:SchemaStatements#remove_check_constraint]
822
- def remove_check_constraint(*args)
823
- @base.remove_check_constraint(name, *args)
822
+ def remove_check_constraint(*args, **options)
823
+ @base.remove_check_constraint(name, *args, **options)
824
824
  end
825
825
  end
826
826
  end
@@ -3,6 +3,8 @@
3
3
  module ActiveRecord
4
4
  module ConnectionAdapters # :nodoc:
5
5
  class SchemaDumper < SchemaDumper # :nodoc:
6
+ DEFAULT_DATETIME_PRECISION = 6 # :nodoc:
7
+
6
8
  def self.create(connection, options)
7
9
  new(connection, options)
8
10
  end
@@ -63,7 +65,18 @@ module ActiveRecord
63
65
  end
64
66
 
65
67
  def schema_precision(column)
66
- column.precision.inspect if column.precision
68
+ if column.type == :datetime
69
+ case column.precision
70
+ when nil
71
+ "nil"
72
+ when DEFAULT_DATETIME_PRECISION
73
+ nil
74
+ else
75
+ column.precision.inspect
76
+ end
77
+ elsif column.precision
78
+ column.precision.inspect
79
+ end
67
80
  end
68
81
 
69
82
  def schema_scale(column)
@@ -1438,7 +1438,7 @@ module ActiveRecord
1438
1438
 
1439
1439
  checks = []
1440
1440
 
1441
- if !options.key?(:name) && column_name.is_a?(String) && /\W/.match?(column_name)
1441
+ if !options.key?(:name) && expression_column_name?(column_name)
1442
1442
  options[:name] = index_name(table_name, column_name)
1443
1443
  column_names = []
1444
1444
  else
@@ -1447,7 +1447,7 @@ module ActiveRecord
1447
1447
 
1448
1448
  checks << lambda { |i| i.name == options[:name].to_s } if options.key?(:name)
1449
1449
 
1450
- if column_names.present?
1450
+ if column_names.present? && !(options.key?(:name) && expression_column_name?(column_names))
1451
1451
  checks << lambda { |i| index_name(table_name, i.columns) == index_name(table_name, column_names) }
1452
1452
  end
1453
1453
 
@@ -1515,7 +1515,7 @@ module ActiveRecord
1515
1515
  end
1516
1516
 
1517
1517
  def index_column_names(column_names)
1518
- if column_names.is_a?(String) && /\W/.match?(column_names)
1518
+ if expression_column_name?(column_names)
1519
1519
  column_names
1520
1520
  else
1521
1521
  Array(column_names)
@@ -1523,13 +1523,18 @@ module ActiveRecord
1523
1523
  end
1524
1524
 
1525
1525
  def index_name_options(column_names)
1526
- if column_names.is_a?(String) && /\W/.match?(column_names)
1526
+ if expression_column_name?(column_names)
1527
1527
  column_names = column_names.scan(/\w+/).join("_")
1528
1528
  end
1529
1529
 
1530
1530
  { column: column_names }
1531
1531
  end
1532
1532
 
1533
+ # Try to identify whether the given column name is an expression
1534
+ def expression_column_name?(column_name)
1535
+ column_name.is_a?(String) && /\W/.match?(column_name)
1536
+ end
1537
+
1533
1538
  def strip_table_name_prefix_and_suffix(table_name)
1534
1539
  prefix = Base.table_name_prefix
1535
1540
  suffix = Base.table_name_suffix
@@ -197,7 +197,7 @@ module ActiveRecord
197
197
 
198
198
  # Executes the SQL statement in the context of this connection.
199
199
  def execute(sql, name = nil, async: false)
200
- raw_execute(sql, name, async)
200
+ raw_execute(sql, name, async: async)
201
201
  end
202
202
 
203
203
  # Mysql2Adapter doesn't have to free a result after using it, but we use this method
@@ -100,8 +100,8 @@ module ActiveRecord
100
100
  statements = statements.map { |sql| transform_query(sql) }
101
101
  combine_multi_statements(statements).each do |statement|
102
102
  raw_execute(statement, name)
103
+ @connection.abandon_results!
103
104
  end
104
- @connection.abandon_results!
105
105
  end
106
106
 
107
107
  def default_insert_value(column)
@@ -53,7 +53,13 @@ module ActiveRecord
53
53
  end
54
54
 
55
55
  def schema_precision(column)
56
- super unless /\A(?:date)?time(?:stamp)?\b/.match?(column.sql_type) && column.precision == 0
56
+ if /\Atime(?:stamp)?\b/.match?(column.sql_type) && column.precision == 0
57
+ nil
58
+ elsif column.type == :datetime
59
+ column.precision == 0 ? "nil" : super
60
+ else
61
+ super
62
+ end
57
63
  end
58
64
 
59
65
  def schema_collation(column)
@@ -163,6 +163,7 @@ module ActiveRecord
163
163
  default, default_function = field[:Default], nil
164
164
 
165
165
  if type_metadata.type == :datetime && /\ACURRENT_TIMESTAMP(?:\([0-6]?\))?\z/i.match?(default)
166
+ default = "#{default} ON UPDATE #{default}" if /on update CURRENT_TIMESTAMP/i.match?(field[:Extra])
166
167
  default, default_function = nil, default
167
168
  elsif type_metadata.extra == "DEFAULT_GENERATED"
168
169
  default = +"(#{default})" unless default.start_with?("(")
@@ -10,6 +10,8 @@ module ActiveRecord
10
10
  end
11
11
 
12
12
  def cast_value(value)
13
+ return if value.blank?
14
+
13
15
  time = super
14
16
  return time if time.is_a?(ActiveSupport::TimeWithZone)
15
17
 
@@ -525,7 +525,7 @@ module ActiveRecord
525
525
  scope = quoted_scope(table_name)
526
526
 
527
527
  check_info = exec_query(<<-SQL, "SCHEMA")
528
- SELECT conname, pg_get_constraintdef(c.oid) AS constraintdef, c.convalidated AS valid
528
+ SELECT conname, pg_get_constraintdef(c.oid, true) AS constraintdef, c.convalidated AS valid
529
529
  FROM pg_constraint c
530
530
  JOIN pg_class t ON c.conrelid = t.oid
531
531
  WHERE c.contype = 'c'
@@ -537,7 +537,7 @@ module ActiveRecord
537
537
  name: row["conname"],
538
538
  validate: row["valid"]
539
539
  }
540
- expression = row["constraintdef"][/CHECK \({2}(.+)\){2}/, 1]
540
+ expression = row["constraintdef"][/CHECK \((.+)\)/m, 1]
541
541
 
542
542
  CheckConstraintDefinition.new(table_name, expression, options)
543
543
  end
@@ -663,7 +663,12 @@ module ActiveRecord
663
663
  column_name, type, default, notnull, oid, fmod, collation, comment, attgenerated = field
664
664
  type_metadata = fetch_type_metadata(column_name, type, oid.to_i, fmod.to_i)
665
665
  default_value = extract_value_from_default(default)
666
- default_function = extract_default_function(default_value, default)
666
+
667
+ if attgenerated.present?
668
+ default_function = default
669
+ else
670
+ default_function = extract_default_function(default_value, default)
671
+ end
667
672
 
668
673
  if match = default_function&.match(/\Anextval\('"?(?<sequence_name>.+_(?<suffix>seq\d*))"?'::regclass\)\z/)
669
674
  serial = sequence_name_from_parts(table_name, column_name, match[:suffix]) == match[:sequence_name]
@@ -75,7 +75,7 @@ module ActiveRecord
75
75
 
76
76
  class << self
77
77
  def new_client(conn_params)
78
- PG.connect(conn_params)
78
+ PG.connect(**conn_params)
79
79
  rescue ::PG::Error => error
80
80
  if conn_params && conn_params[:dbname] && error.message.include?(conn_params[:dbname])
81
81
  raise ActiveRecord::NoDatabaseError.db_error(conn_params[:dbname])
@@ -281,7 +281,7 @@ module ActiveRecord
281
281
  def initialize(connection, logger, connection_parameters, config)
282
282
  super(connection, logger, config)
283
283
 
284
- @connection_parameters = connection_parameters
284
+ @connection_parameters = connection_parameters || {}
285
285
 
286
286
  # @local_tz is initialized as nil to avoid warnings when connect tries to use it
287
287
  @local_tz = nil
@@ -45,6 +45,19 @@ module ActiveRecord
45
45
  0
46
46
  end
47
47
 
48
+ def quote_default_expression(value, column) # :nodoc:
49
+ if value.is_a?(Proc)
50
+ value = value.call
51
+ if value.match?(/\A\w+\(.*\)\z/)
52
+ "(#{value})"
53
+ else
54
+ value
55
+ end
56
+ else
57
+ super
58
+ end
59
+ end
60
+
48
61
  def type_cast(value) # :nodoc:
49
62
  case value
50
63
  when BigDecimal
@@ -127,20 +127,20 @@ module ActiveRecord
127
127
  end
128
128
 
129
129
  def new_column_from_field(table_name, field)
130
- default = \
131
- case field["dflt_value"]
132
- when /^null$/i
133
- nil
134
- when /^'(.*)'$/m
135
- $1.gsub("''", "'")
136
- when /^"(.*)"$/m
137
- $1.gsub('""', '"')
138
- else
139
- field["dflt_value"]
140
- end
130
+ default = field["dflt_value"]
141
131
 
142
132
  type_metadata = fetch_type_metadata(field["type"])
143
- Column.new(field["name"], default, type_metadata, field["notnull"].to_i == 0, collation: field["collation"])
133
+ default_value = extract_value_from_default(default)
134
+ default_function = extract_default_function(default_value, default)
135
+
136
+ Column.new(
137
+ field["name"],
138
+ default_value,
139
+ type_metadata,
140
+ field["notnull"].to_i == 0,
141
+ default_function,
142
+ collation: field["collation"]
143
+ )
144
144
  end
145
145
 
146
146
  def data_source_sql(name = nil, type: nil)
@@ -389,6 +389,34 @@ module ActiveRecord
389
389
  end
390
390
  alias column_definitions table_structure
391
391
 
392
+ def extract_value_from_default(default)
393
+ case default
394
+ when /^null$/i
395
+ nil
396
+ # Quoted types
397
+ when /^'(.*)'$/m
398
+ $1.gsub("''", "'")
399
+ # Quoted types
400
+ when /^"(.*)"$/m
401
+ $1.gsub('""', '"')
402
+ # Numeric types
403
+ when /\A-?\d+(\.\d*)?\z/
404
+ $&
405
+ else
406
+ # Anything else is blank or some function
407
+ # and we can't know the value of that, so return nil.
408
+ nil
409
+ end
410
+ end
411
+
412
+ def extract_default_function(default_value, default)
413
+ default if has_default_function?(default_value, default)
414
+ end
415
+
416
+ def has_default_function?(default_value, default)
417
+ !default_value && %r{\w+\(.*\)|CURRENT_TIME|CURRENT_DATE|CURRENT_TIMESTAMP}.match?(default)
418
+ end
419
+
392
420
  # See: https://www.sqlite.org/lang_altertable.html
393
421
  # SQLite has an additional restriction on the ALTER TABLE statement
394
422
  def invalid_alter_table_type?(type, options)
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "uri"
4
4
  require "active_support/core_ext/enumerable"
5
+ require "active_support/core_ext/hash/reverse_merge"
5
6
 
6
7
  module ActiveRecord
7
8
  class DatabaseConfigurations
@@ -38,7 +38,7 @@ module ActiveRecord
38
38
  # the returned list. Most of the time we're only iterating over the write
39
39
  # connection (i.e. migrations don't need to run for the write and read connection).
40
40
  # Defaults to +false+.
41
- # * <tt>include_hidden:</tte Determines whether to include replicas and configurations
41
+ # * <tt>include_hidden:</tt> Determines whether to include replicas and configurations
42
42
  # hidden by +database_tasks: false+ in the returned list. Most of the time we're only
43
43
  # iterating over the primary connections (i.e. migrations don't need to run for the
44
44
  # write and read connection). Defaults to +false+.
@@ -50,9 +50,9 @@ module ActiveRecord
50
50
  end
51
51
  end
52
52
 
53
- def install_auto_filtered_parameters(application) # :nodoc:
53
+ def install_auto_filtered_parameters_hook(application) # :nodoc:
54
54
  ActiveRecord::Encryption.on_encrypted_attribute_declared do |klass, encrypted_attribute_name|
55
- application.config.filter_parameters << encrypted_attribute_name unless ActiveRecord::Encryption.config.excluded_from_filter_parameters.include?(name)
55
+ application.config.filter_parameters << encrypted_attribute_name unless ActiveRecord::Encryption.config.excluded_from_filter_parameters.include?(encrypted_attribute_name)
56
56
  end
57
57
  end
58
58
  end
@@ -1,35 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Automatically expand encrypted arguments to support querying both encrypted and unencrypted data
4
- #
5
- # Active Record Encryption supports querying the db using deterministic attributes. For example:
6
- #
7
- # Contact.find_by(email_address: "jorge@hey.com")
8
- #
9
- # The value "jorge@hey.com" will get encrypted automatically to perform the query. But there is
10
- # a problem while the data is being encrypted. This won't work. During that time, you need these
11
- # queries to be:
12
- #
13
- # Contact.find_by(email_address: [ "jorge@hey.com", "<encrypted jorge@hey.com>" ])
14
- #
15
- # This patches ActiveRecord to support this automatically. It addresses both:
16
- #
17
- # * ActiveRecord::Base: Used in +Contact.find_by_email_address(...)+
18
- # * ActiveRecord::Relation: Used in +Contact.internal.find_by_email_address(...)+
19
- #
20
- # +ActiveRecord::Base+ relies on +ActiveRecord::Relation+ (+ActiveRecord::QueryMethods+) but it does
21
- # some prepared statements caching. That's why we need to intercept +ActiveRecord::Base+ as soon
22
- # as it's invoked (so that the proper prepared statement is cached).
23
- #
24
- # When modifying this file run performance tests in +test/performance/extended_deterministic_queries_performance_test.rb+ to
25
- # make sure performance overhead is acceptable.
26
- #
27
- # We will extend this to support previous "encryption context" versions in future iterations
28
- #
29
- # @TODO Experimental. Support for every kind of query is pending
30
- # @TODO It should not patch anything if not needed (no previous schemes or no support for previous encryption schemes)
31
3
  module ActiveRecord
32
4
  module Encryption
5
+ # Automatically expand encrypted arguments to support querying both encrypted and unencrypted data
6
+ #
7
+ # Active Record Encryption supports querying the db using deterministic attributes. For example:
8
+ #
9
+ # Contact.find_by(email_address: "jorge@hey.com")
10
+ #
11
+ # The value "jorge@hey.com" will get encrypted automatically to perform the query. But there is
12
+ # a problem while the data is being encrypted. This won't work. During that time, you need these
13
+ # queries to be:
14
+ #
15
+ # Contact.find_by(email_address: [ "jorge@hey.com", "<encrypted jorge@hey.com>" ])
16
+ #
17
+ # This patches ActiveRecord to support this automatically. It addresses both:
18
+ #
19
+ # * ActiveRecord::Base: Used in +Contact.find_by_email_address(...)+
20
+ # * ActiveRecord::Relation: Used in +Contact.internal.find_by_email_address(...)+
21
+ #
22
+ # +ActiveRecord::Base+ relies on +ActiveRecord::Relation+ (+ActiveRecord::QueryMethods+) but it does
23
+ # some prepared statements caching. That's why we need to intercept +ActiveRecord::Base+ as soon
24
+ # as it's invoked (so that the proper prepared statement is cached).
25
+ #
26
+ # When modifying this file run performance tests in +test/performance/extended_deterministic_queries_performance_test.rb+ to
27
+ # make sure performance overhead is acceptable.
28
+ #
29
+ # We will extend this to support previous "encryption context" versions in future iterations
30
+ #
31
+ # @TODO Experimental. Support for every kind of query is pending
32
+ # @TODO It should not patch anything if not needed (no previous schemes or no support for previous encryption schemes)
33
33
  module ExtendedDeterministicQueries
34
34
  def self.install_support
35
35
  ActiveRecord::Relation.prepend(RelationQueries)
@@ -407,7 +407,7 @@ module ActiveRecord
407
407
  # defaults:
408
408
  #
409
409
  # DEFAULTS: &DEFAULTS
410
- # created_on: <%= 3.weeks.ago.to_formatted_s(:db) %>
410
+ # created_on: <%= 3.weeks.ago.to_fs(:db) %>
411
411
  #
412
412
  # first:
413
413
  # name: Smurf
@@ -9,8 +9,8 @@ module ActiveRecord
9
9
  module VERSION
10
10
  MAJOR = 7
11
11
  MINOR = 0
12
- TINY = 0
13
- PRE = nil
12
+ TINY = 2
13
+ PRE = "2"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -79,7 +79,7 @@ module ActiveRecord
79
79
  timestamp = max_updated_column_timestamp
80
80
 
81
81
  if timestamp
82
- timestamp = timestamp.utc.to_formatted_s(cache_timestamp_format)
82
+ timestamp = timestamp.utc.to_fs(cache_timestamp_format)
83
83
  "#{model_name.cache_key}/#{id}-#{timestamp}"
84
84
  else
85
85
  "#{model_name.cache_key}/#{id}"
@@ -103,7 +103,7 @@ module ActiveRecord
103
103
  raw_timestamp_to_cache_version(timestamp)
104
104
 
105
105
  elsif timestamp = updated_at
106
- timestamp.utc.to_formatted_s(cache_timestamp_format)
106
+ timestamp.utc.to_fs(cache_timestamp_format)
107
107
  end
108
108
  elsif self.class.has_attribute?("updated_at")
109
109
  raise ActiveModel::MissingAttributeError, "missing attribute: updated_at"
@@ -92,6 +92,22 @@ module ActiveRecord
92
92
  end
93
93
  end
94
94
 
95
+ module SQLite3
96
+ module TableDefinition
97
+ def references(*args, **options)
98
+ args.each do |ref_name|
99
+ ReferenceDefinition.new(ref_name, type: :integer, **options).add_to(self)
100
+ end
101
+ end
102
+ alias :belongs_to :references
103
+
104
+ def column(name, type, index: nil, **options)
105
+ options[:precision] ||= nil
106
+ super
107
+ end
108
+ end
109
+ end
110
+
95
111
  module TableDefinition
96
112
  def references(*args, **options)
97
113
  args.each do |ref_name|
@@ -131,8 +147,13 @@ module ActiveRecord
131
147
  end
132
148
 
133
149
  def add_reference(table_name, ref_name, **options)
134
- ReferenceDefinition.new(ref_name, **options)
135
- .add_to(connection.update_table_definition(table_name, self))
150
+ if connection.adapter_name == "SQLite"
151
+ reference_definition = ReferenceDefinition.new(ref_name, type: :integer, **options)
152
+ else
153
+ reference_definition = ReferenceDefinition.new(ref_name, **options)
154
+ end
155
+
156
+ reference_definition.add_to(connection.update_table_definition(table_name, self))
136
157
  end
137
158
  alias :add_belongs_to :add_reference
138
159
 
@@ -140,6 +161,7 @@ module ActiveRecord
140
161
  def compatible_table_definition(t)
141
162
  class << t
142
163
  prepend TableDefinition
164
+ prepend SQLite3::TableDefinition
143
165
  end
144
166
  t
145
167
  end
@@ -1001,7 +1001,7 @@ module ActiveRecord
1001
1001
  # Determines the version number of the next migration.
1002
1002
  def next_migration_number(number)
1003
1003
  if ActiveRecord.timestamped_migrations
1004
- [Time.now.utc.strftime("%Y%m%d%H%M%S").to_i, ("%.14d" % number).to_i].max
1004
+ [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % number].max
1005
1005
  else
1006
1006
  SchemaMigration.normalize_migration_number(number)
1007
1007
  end
@@ -360,9 +360,9 @@ To keep using the current cache store, you can turn off cache versioning entirel
360
360
  end
361
361
 
362
362
  # Filtered params
363
- ActiveSupport.on_load(:action_controller) do
363
+ ActiveSupport.on_load(:action_controller, run_once: true) do
364
364
  if ActiveRecord::Encryption.config.add_to_filter_parameters
365
- ActiveRecord::Encryption.install_auto_filtered_parameters(app)
365
+ ActiveRecord::Encryption.install_auto_filtered_parameters_hook(app)
366
366
  end
367
367
  end
368
368
  end
@@ -1031,7 +1031,7 @@ module ActiveRecord
1031
1031
  end
1032
1032
 
1033
1033
  def join_scopes(table, predicate_builder, klass = self.klass, record = nil) # :nodoc:
1034
- scopes = @previous_reflection.join_scopes(table, predicate_builder, record) + super
1034
+ scopes = @previous_reflection.join_scopes(table, predicate_builder, klass, record) + super
1035
1035
  scopes << build_scope(table, predicate_builder, klass).instance_exec(record, &source_type_scope)
1036
1036
  end
1037
1037
 
@@ -155,7 +155,7 @@ module ActiveRecord
155
155
  end
156
156
 
157
157
  # Use #pluck as a shortcut to select one or more attributes without
158
- # loading a bunch of records just to grab the attributes you want.
158
+ # loading an entire record object per row.
159
159
  #
160
160
  # Person.pluck(:name)
161
161
  #
@@ -345,12 +345,13 @@ module ActiveRecord
345
345
  column = aggregate_column(column_name)
346
346
  column_alias = column_alias_for("#{operation} #{column_name.to_s.downcase}")
347
347
  select_value = operation_over_aggregate_column(column, operation, distinct)
348
- select_value.as(column_alias)
348
+ select_value.as(connection.quote_column_name(column_alias))
349
349
 
350
350
  select_values = [select_value]
351
351
  select_values += self.select_values unless having_clause.empty?
352
352
 
353
353
  select_values.concat group_columns.map { |aliaz, field|
354
+ aliaz = connection.quote_column_name(aliaz)
354
355
  if field.respond_to?(:as)
355
356
  field.as(aliaz)
356
357
  else
@@ -87,7 +87,7 @@ module ActiveRecord
87
87
 
88
88
  delegate :to_xml, :encode_with, :length, :each, :join,
89
89
  :[], :&, :|, :+, :-, :sample, :reverse, :rotate, :compact, :in_groups, :in_groups_of,
90
- :to_sentence, :to_formatted_s, :as_json,
90
+ :to_sentence, :to_fs, :to_formatted_s, :as_json,
91
91
  :shuffle, :split, :slice, :index, :rindex, to: :records
92
92
 
93
93
  delegate :primary_key, :connection, to: :klass
@@ -68,7 +68,7 @@ module ActiveRecord
68
68
  # # WHERE "authors"."id" IS NOT NULL AND "comments"."id" IS NOT NULL
69
69
  def associated(*associations)
70
70
  associations.each do |association|
71
- reflection = @scope.klass._reflect_on_association(association)
71
+ reflection = scope_association_reflection(association)
72
72
  @scope.joins!(association)
73
73
  self.not(reflection.table_name => { reflection.association_primary_key => nil })
74
74
  end
@@ -96,13 +96,22 @@ module ActiveRecord
96
96
  # # WHERE "authors"."id" IS NULL AND "comments"."id" IS NULL
97
97
  def missing(*associations)
98
98
  associations.each do |association|
99
- reflection = @scope.klass._reflect_on_association(association)
99
+ reflection = scope_association_reflection(association)
100
100
  @scope.left_outer_joins!(association)
101
101
  @scope.where!(reflection.table_name => { reflection.association_primary_key => nil })
102
102
  end
103
103
 
104
104
  @scope
105
105
  end
106
+
107
+ private
108
+ def scope_association_reflection(association)
109
+ reflection = @scope.klass._reflect_on_association(association)
110
+ unless reflection
111
+ raise ArgumentError.new("An association named `:#{association}` does not exist on the model `#{@scope.name}`.")
112
+ end
113
+ reflection
114
+ end
106
115
  end
107
116
 
108
117
  FROZEN_EMPTY_ARRAY = [].freeze
@@ -424,18 +433,23 @@ module ActiveRecord
424
433
  # adapter this will either use a CASE statement or a built-in function.
425
434
  #
426
435
  # User.in_order_of(:id, [1, 5, 3])
427
- # # SELECT "users".* FROM "users" ORDER BY FIELD("users"."id", 1, 5, 3)
436
+ # # SELECT "users".* FROM "users"
437
+ # # ORDER BY FIELD("users"."id", 1, 5, 3)
438
+ # # WHERE "users"."id" IN (1, 5, 3)
428
439
  #
429
440
  def in_order_of(column, values)
430
441
  klass.disallow_raw_sql!([column], permit: connection.column_name_with_order_matcher)
442
+ return spawn.none! if values.empty?
431
443
 
432
444
  references = column_references([column])
433
445
  self.references_values |= references unless references.empty?
434
446
 
435
447
  values = values.map { |value| type_caster.type_cast_for_database(column, value) }
436
- column = order_column(column.to_s) if column.is_a?(Symbol)
448
+ arel_column = column.is_a?(Symbol) ? order_column(column.to_s) : column
437
449
 
438
- spawn.order!(connection.field_ordered_value(column, values))
450
+ spawn
451
+ .order!(connection.field_ordered_value(arel_column, values))
452
+ .where!(arel_column.in(values))
439
453
  end
440
454
 
441
455
  # Replaces any existing order defined on the relation with the specified order.
@@ -388,7 +388,7 @@ module ActiveRecord
388
388
  end
389
389
 
390
390
  if timestamp
391
- "#{size}-#{timestamp.utc.to_formatted_s(cache_timestamp_format)}"
391
+ "#{size}-#{timestamp.utc.to_fs(cache_timestamp_format)}"
392
392
  else
393
393
  "#{size}"
394
394
  end
@@ -646,6 +646,21 @@ module ActiveRecord
646
646
  # Schedule the query to be performed from a background thread pool.
647
647
  #
648
648
  # Post.where(published: true).load_async # => #<ActiveRecord::Relation>
649
+ #
650
+ # When the +Relation+ is iterated, if the background query wasn't executed yet,
651
+ # it will be performed by the foreground thread.
652
+ #
653
+ # Note that {config.active_record.async_query_executor}[https://guides.rubyonrails.org/configuring.html#config-active-record-async-query-executor] must be configured
654
+ # for queries to actually be executed concurrently. Otherwise it defaults to
655
+ # executing them in the foreground.
656
+ #
657
+ # +load_async+ will also fallback to executing in the foreground in the test environment when transactional
658
+ # fixtures are enabled.
659
+ #
660
+ # If the query was actually executed in the background, the Active Record logs will show
661
+ # it by prefixing the log line with <tt>ASYNC</tt>:
662
+ #
663
+ # ASYNC Post Load (0.0ms) (db time 2ms) SELECT "posts".* FROM "posts" LIMIT 100
649
664
  def load_async
650
665
  return load if !connection.async_enabled?
651
666
 
@@ -10,7 +10,7 @@ module ActiveRecord
10
10
  #
11
11
  # Usage:
12
12
  #
13
- # ActiveRecord::Schema.define do
13
+ # ActiveRecord::Schema[7.0].define do
14
14
  # create_table :authors do |t|
15
15
  # t.string :name, null: false
16
16
  # end
@@ -30,32 +30,47 @@ module ActiveRecord
30
30
  # ActiveRecord::Schema is only supported by database adapters that also
31
31
  # support migrations, the two features being very similar.
32
32
  class Schema < Migration::Current
33
- # Eval the given block. All methods available to the current connection
34
- # adapter are available within the block, so you can easily use the
35
- # database definition DSL to build up your schema (
36
- # {create_table}[rdoc-ref:ConnectionAdapters::SchemaStatements#create_table],
37
- # {add_index}[rdoc-ref:ConnectionAdapters::SchemaStatements#add_index], etc.).
38
- #
39
- # The +info+ hash is optional, and if given is used to define metadata
40
- # about the current schema (currently, only the schema's version):
41
- #
42
- # ActiveRecord::Schema.define(version: 2038_01_19_000001) do
43
- # ...
44
- # end
45
- def self.define(info = {}, &block)
46
- new.define(info, &block)
47
- end
33
+ module Definition
34
+ extend ActiveSupport::Concern
35
+
36
+ module ClassMethods
37
+ # Eval the given block. All methods available to the current connection
38
+ # adapter are available within the block, so you can easily use the
39
+ # database definition DSL to build up your schema (
40
+ # {create_table}[rdoc-ref:ConnectionAdapters::SchemaStatements#create_table],
41
+ # {add_index}[rdoc-ref:ConnectionAdapters::SchemaStatements#add_index], etc.).
42
+ #
43
+ # The +info+ hash is optional, and if given is used to define metadata
44
+ # about the current schema (currently, only the schema's version):
45
+ #
46
+ # ActiveRecord::Schema[7.0].define(version: 2038_01_19_000001) do
47
+ # ...
48
+ # end
49
+ def define(info = {}, &block)
50
+ new.define(info, &block)
51
+ end
52
+ end
53
+
54
+ def define(info, &block) # :nodoc:
55
+ instance_eval(&block)
48
56
 
49
- def define(info, &block) # :nodoc:
50
- instance_eval(&block)
57
+ if info[:version].present?
58
+ connection.schema_migration.create_table
59
+ connection.assume_migrated_upto_version(info[:version])
60
+ end
51
61
 
52
- if info[:version].present?
53
- connection.schema_migration.create_table
54
- connection.assume_migrated_upto_version(info[:version])
62
+ ActiveRecord::InternalMetadata.create_table
63
+ ActiveRecord::InternalMetadata[:environment] = connection.migration_context.current_environment
55
64
  end
65
+ end
66
+
67
+ include Definition
56
68
 
57
- ActiveRecord::InternalMetadata.create_table
58
- ActiveRecord::InternalMetadata[:environment] = connection.migration_context.current_environment
69
+ def self.[](version)
70
+ @class_for_version ||= {}
71
+ @class_for_version[version] ||= Class.new(Migration::Compatibility.find(version)) do
72
+ include Definition
73
+ end
59
74
  end
60
75
  end
61
76
  end
@@ -74,22 +74,21 @@ module ActiveRecord
74
74
  end
75
75
 
76
76
  def header(stream)
77
- stream.puts <<HEADER
78
- # This file is auto-generated from the current state of the database. Instead
79
- # of editing this file, please use the migrations feature of Active Record to
80
- # incrementally modify your database, and then regenerate this schema definition.
81
- #
82
- # This file is the source Rails uses to define your schema when running `bin/rails
83
- # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
84
- # be faster and is potentially less error prone than running all of your
85
- # migrations from scratch. Old migrations may fail to apply correctly if those
86
- # migrations use external dependencies or application code.
87
- #
88
- # It's strongly recommended that you check this file into your version control system.
89
-
90
- ActiveRecord::Schema.define(#{define_params}) do
91
-
92
- HEADER
77
+ stream.puts <<~HEADER
78
+ # This file is auto-generated from the current state of the database. Instead
79
+ # of editing this file, please use the migrations feature of Active Record to
80
+ # incrementally modify your database, and then regenerate this schema definition.
81
+ #
82
+ # This file is the source Rails uses to define your schema when running `bin/rails
83
+ # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
84
+ # be faster and is potentially less error prone than running all of your
85
+ # migrations from scratch. Old migrations may fail to apply correctly if those
86
+ # migrations use external dependencies or application code.
87
+ #
88
+ # It's strongly recommended that you check this file into your version control system.
89
+
90
+ ActiveRecord::Schema[#{ActiveRecord::Migration.current_version}].define(#{define_params}) do
91
+ HEADER
93
92
  end
94
93
 
95
94
  def trailer(stream)
@@ -257,8 +257,12 @@ module ActiveRecord
257
257
  scope = ENV["SCOPE"]
258
258
  verbose_was, Migration.verbose = Migration.verbose, verbose?
259
259
 
260
- Base.connection.migration_context.migrate(target_version || version) do |migration|
261
- scope.blank? || scope == migration.scope
260
+ Base.connection.migration_context.migrate(target_version) do |migration|
261
+ if version.blank?
262
+ scope.blank? || scope == migration.scope
263
+ else
264
+ migration.version == version
265
+ end
262
266
  end.tap do |migrations_ran|
263
267
  Migration.write("No migrations ran. (using #{scope} scope)") if scope.present? && migrations_ran.empty?
264
268
  end
@@ -58,7 +58,7 @@ module ActiveRecord
58
58
  end
59
59
 
60
60
  args = ["--schema-only", "--no-privileges", "--no-owner"]
61
- args << "--no-comment" if connection.database_version >= 110_000
61
+ args << "--no-comments" if connection.database_version >= 110_000
62
62
  args.concat(["--file", filename])
63
63
 
64
64
  args.concat(Array(extra_flags)) if extra_flags
data/lib/active_record.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # Copyright (c) 2004-2021 David Heinemeier Hansson
4
+ # Copyright (c) 2004-2022 David Heinemeier Hansson
5
5
  #
6
6
  # Permission is hereby granted, free of charge, to any person obtaining
7
7
  # a copy of this software and associated documentation files (the
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.0.0
4
+ version: 7.0.2.2
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: 2021-12-15 00:00:00.000000000 Z
11
+ date: 2022-02-11 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.0.0
19
+ version: 7.0.2.2
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.0.0
26
+ version: 7.0.2.2
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.0.0
33
+ version: 7.0.2.2
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.0.0
40
+ version: 7.0.2.2
41
41
  description: Databases on Rails. Build a persistent domain model by mapping database
42
42
  tables to Ruby classes. Strong conventions for associations, validations, aggregations,
43
43
  migrations, and testing come baked-in.
@@ -434,12 +434,12 @@ licenses:
434
434
  - MIT
435
435
  metadata:
436
436
  bug_tracker_uri: https://github.com/rails/rails/issues
437
- changelog_uri: https://github.com/rails/rails/blob/v7.0.0/activerecord/CHANGELOG.md
438
- documentation_uri: https://api.rubyonrails.org/v7.0.0/
437
+ changelog_uri: https://github.com/rails/rails/blob/v7.0.2.2/activerecord/CHANGELOG.md
438
+ documentation_uri: https://api.rubyonrails.org/v7.0.2.2/
439
439
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
440
- source_code_uri: https://github.com/rails/rails/tree/v7.0.0/activerecord
440
+ source_code_uri: https://github.com/rails/rails/tree/v7.0.2.2/activerecord
441
441
  rubygems_mfa_required: 'true'
442
- post_install_message:
442
+ post_install_message:
443
443
  rdoc_options:
444
444
  - "--main"
445
445
  - README.rdoc
@@ -456,8 +456,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
456
456
  - !ruby/object:Gem::Version
457
457
  version: '0'
458
458
  requirements: []
459
- rubygems_version: 3.2.32
460
- signing_key:
459
+ rubygems_version: 3.2.22
460
+ signing_key:
461
461
  specification_version: 4
462
462
  summary: Object-relational mapper framework (part of Rails).
463
463
  test_files: []