activerecord 7.2.1.1 → 8.0.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +220 -756
- data/README.rdoc +1 -1
- data/lib/active_record/associations/association.rb +25 -5
- data/lib/active_record/associations/builder/association.rb +7 -6
- data/lib/active_record/associations/collection_association.rb +10 -8
- data/lib/active_record/associations/disable_joins_association_scope.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +10 -3
- data/lib/active_record/associations/join_dependency/join_association.rb +3 -2
- data/lib/active_record/associations/join_dependency.rb +4 -4
- data/lib/active_record/associations/preloader/association.rb +2 -2
- data/lib/active_record/associations/singular_association.rb +8 -3
- data/lib/active_record/associations.rb +34 -4
- data/lib/active_record/asynchronous_queries_tracker.rb +28 -24
- data/lib/active_record/attribute_assignment.rb +9 -1
- data/lib/active_record/attribute_methods/primary_key.rb +2 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -12
- data/lib/active_record/attributes.rb +1 -2
- data/lib/active_record/autosave_association.rb +69 -27
- data/lib/active_record/callbacks.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +16 -10
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +26 -9
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +90 -43
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +12 -4
- data/lib/active_record/connection_adapters/abstract/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +7 -2
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +34 -7
- data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -5
- data/lib/active_record/connection_adapters/abstract_adapter.rb +24 -26
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +28 -42
- data/lib/active_record/connection_adapters/mysql/quoting.rb +0 -8
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +2 -8
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +43 -45
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +42 -98
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -8
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -42
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +10 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -4
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +0 -11
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -11
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +54 -14
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +45 -97
- data/lib/active_record/connection_adapters/schema_cache.rb +1 -3
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +76 -100
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +0 -6
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +13 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +8 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +53 -12
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +37 -67
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +0 -17
- data/lib/active_record/connection_adapters.rb +0 -56
- data/lib/active_record/connection_handling.rb +22 -0
- data/lib/active_record/core.rb +28 -18
- data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -1
- data/lib/active_record/encryption/config.rb +3 -1
- data/lib/active_record/encryption/encryptable_record.rb +4 -4
- data/lib/active_record/encryption/encrypted_attribute_type.rb +10 -1
- data/lib/active_record/encryption/encryptor.rb +15 -8
- data/lib/active_record/encryption/extended_deterministic_queries.rb +4 -2
- data/lib/active_record/encryption/key_provider.rb +1 -1
- data/lib/active_record/encryption/scheme.rb +8 -1
- data/lib/active_record/encryption.rb +2 -0
- data/lib/active_record/enum.rb +54 -75
- data/lib/active_record/errors.rb +13 -5
- data/lib/active_record/fixtures.rb +0 -2
- data/lib/active_record/future_result.rb +14 -10
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/insert_all.rb +1 -1
- data/lib/active_record/locking/optimistic.rb +1 -1
- data/lib/active_record/log_subscriber.rb +5 -11
- data/lib/active_record/marshalling.rb +4 -1
- data/lib/active_record/migration/command_recorder.rb +22 -5
- data/lib/active_record/migration/compatibility.rb +5 -2
- data/lib/active_record/migration.rb +35 -38
- data/lib/active_record/model_schema.rb +4 -6
- data/lib/active_record/nested_attributes.rb +11 -2
- data/lib/active_record/persistence.rb +128 -130
- data/lib/active_record/query_cache.rb +0 -4
- data/lib/active_record/query_logs.rb +102 -50
- data/lib/active_record/query_logs_formatter.rb +17 -28
- data/lib/active_record/querying.rb +8 -8
- data/lib/active_record/railtie.rb +9 -38
- data/lib/active_record/railties/databases.rake +1 -1
- data/lib/active_record/reflection.rb +23 -23
- data/lib/active_record/relation/batches/batch_enumerator.rb +4 -3
- data/lib/active_record/relation/batches.rb +132 -72
- data/lib/active_record/relation/calculations.rb +41 -40
- data/lib/active_record/relation/delegation.rb +25 -14
- data/lib/active_record/relation/finder_methods.rb +18 -18
- data/lib/active_record/relation/merger.rb +8 -8
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -1
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +4 -3
- data/lib/active_record/relation/predicate_builder.rb +14 -1
- data/lib/active_record/relation/query_methods.rb +122 -71
- data/lib/active_record/relation/spawn_methods.rb +1 -1
- data/lib/active_record/relation.rb +79 -61
- data/lib/active_record/result.rb +66 -4
- data/lib/active_record/sanitization.rb +7 -6
- data/lib/active_record/schema_dumper.rb +5 -0
- data/lib/active_record/schema_migration.rb +2 -1
- data/lib/active_record/scoping/named.rb +5 -2
- data/lib/active_record/statement_cache.rb +12 -12
- data/lib/active_record/store.rb +7 -3
- data/lib/active_record/table_metadata.rb +1 -3
- data/lib/active_record/tasks/database_tasks.rb +40 -47
- data/lib/active_record/tasks/mysql_database_tasks.rb +0 -2
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -2
- data/lib/active_record/test_fixtures.rb +12 -0
- data/lib/active_record/testing/query_assertions.rb +2 -2
- data/lib/active_record/token_for.rb +1 -1
- data/lib/active_record/validations/uniqueness.rb +9 -8
- data/lib/active_record.rb +15 -45
- data/lib/arel/collectors/bind.rb +1 -1
- data/lib/arel/table.rb +3 -7
- data/lib/arel/visitors/sqlite.rb +25 -0
- metadata +10 -11
- data/lib/active_record/relation/record_fetch_warning.rb +0 -52
@@ -12,7 +12,7 @@ module ActiveRecord
|
|
12
12
|
@keys = Array(keys)
|
13
13
|
end
|
14
14
|
|
15
|
-
# Returns the
|
15
|
+
# Returns the last key in the list as the active key to perform encryptions
|
16
16
|
#
|
17
17
|
# When +ActiveRecord::Encryption.config.store_key_references+ is true, the key will include
|
18
18
|
# a public tag referencing the key itself. That key will be stored in the public
|
@@ -11,7 +11,7 @@ module ActiveRecord
|
|
11
11
|
attr_accessor :previous_schemes
|
12
12
|
|
13
13
|
def initialize(key_provider: nil, key: nil, deterministic: nil, support_unencrypted_data: nil, downcase: nil, ignore_case: nil,
|
14
|
-
previous_schemes: nil, **context_properties)
|
14
|
+
previous_schemes: nil, compress: true, compressor: nil, **context_properties)
|
15
15
|
# Initializing all attributes to +nil+ as we want to allow a "not set" semantics so that we
|
16
16
|
# can merge schemes without overriding values with defaults. See +#merge+
|
17
17
|
|
@@ -24,8 +24,13 @@ module ActiveRecord
|
|
24
24
|
@previous_schemes_param = previous_schemes
|
25
25
|
@previous_schemes = Array.wrap(previous_schemes)
|
26
26
|
@context_properties = context_properties
|
27
|
+
@compress = compress
|
28
|
+
@compressor = compressor
|
27
29
|
|
28
30
|
validate_config!
|
31
|
+
|
32
|
+
@context_properties[:encryptor] = Encryptor.new(compress: @compress) unless @compress
|
33
|
+
@context_properties[:encryptor] = Encryptor.new(compressor: compressor) if compressor
|
29
34
|
end
|
30
35
|
|
31
36
|
def ignore_case?
|
@@ -78,6 +83,8 @@ module ActiveRecord
|
|
78
83
|
def validate_config!
|
79
84
|
raise Errors::Configuration, "ignore_case: can only be used with deterministic encryption" if @ignore_case && !@deterministic
|
80
85
|
raise Errors::Configuration, "key_provider: and key: can't be used simultaneously" if @key_provider_param && @key
|
86
|
+
raise Errors::Configuration, "compressor: can't be used with compress: false" if !@compress && @compressor
|
87
|
+
raise Errors::Configuration, "compressor: can't be used with encryptor" if @compressor && @context_properties[:encryptor]
|
81
88
|
end
|
82
89
|
|
83
90
|
def key_provider_from_key
|
data/lib/active_record/enum.rb
CHANGED
@@ -167,15 +167,6 @@ module ActiveRecord
|
|
167
167
|
base.class_attribute(:defined_enums, instance_writer: false, default: {})
|
168
168
|
end
|
169
169
|
|
170
|
-
def load_schema! # :nodoc:
|
171
|
-
defined_enums.each_key do |name|
|
172
|
-
unless columns_hash.key?(resolve_attribute_name(name))
|
173
|
-
raise "Unknown enum attribute '#{name}' for #{self.name}. Enums must be" \
|
174
|
-
" backed by a database column."
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
170
|
class EnumType < Type::Value # :nodoc:
|
180
171
|
delegate :type, to: :subtype
|
181
172
|
|
@@ -222,89 +213,77 @@ module ActiveRecord
|
|
222
213
|
attr_reader :name, :mapping
|
223
214
|
end
|
224
215
|
|
225
|
-
def enum(name
|
226
|
-
|
227
|
-
|
228
|
-
return _enum(name, values, **options)
|
229
|
-
end
|
216
|
+
def enum(name, values, prefix: nil, suffix: nil, scopes: true, instance_methods: true, validate: false, **options)
|
217
|
+
assert_valid_enum_definition_values(values)
|
218
|
+
assert_valid_enum_options(options)
|
230
219
|
|
231
|
-
|
232
|
-
|
220
|
+
# statuses = { }
|
221
|
+
enum_values = ActiveSupport::HashWithIndifferentAccess.new
|
222
|
+
name = name.to_s
|
233
223
|
|
234
|
-
|
224
|
+
# def self.statuses() statuses end
|
225
|
+
detect_enum_conflict!(name, name.pluralize, true)
|
226
|
+
singleton_class.define_method(name.pluralize) { enum_values }
|
227
|
+
defined_enums[name] = enum_values
|
235
228
|
|
236
|
-
|
237
|
-
|
238
|
-
in Rails 8.0. Positional arguments should be used instead:
|
229
|
+
detect_enum_conflict!(name, name)
|
230
|
+
detect_enum_conflict!(name, "#{name}=")
|
239
231
|
|
240
|
-
|
241
|
-
MSG
|
242
|
-
end
|
232
|
+
attribute(name, **options)
|
243
233
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
def _enum(name, values, prefix: nil, suffix: nil, scopes: true, instance_methods: true, validate: false, **options)
|
251
|
-
assert_valid_enum_definition_values(values)
|
252
|
-
assert_valid_enum_options(options)
|
253
|
-
# statuses = { }
|
254
|
-
enum_values = ActiveSupport::HashWithIndifferentAccess.new
|
255
|
-
name = name.to_s
|
256
|
-
|
257
|
-
# def self.statuses() statuses end
|
258
|
-
detect_enum_conflict!(name, name.pluralize, true)
|
259
|
-
singleton_class.define_method(name.pluralize) { enum_values }
|
260
|
-
defined_enums[name] = enum_values
|
261
|
-
|
262
|
-
detect_enum_conflict!(name, name)
|
263
|
-
detect_enum_conflict!(name, "#{name}=")
|
234
|
+
decorate_attributes([name]) do |_name, subtype|
|
235
|
+
if subtype == ActiveModel::Type.default_value
|
236
|
+
raise "Undeclared attribute type for enum '#{name}' in #{self.name}. Enums must be" \
|
237
|
+
" backed by a database column or declared with an explicit type" \
|
238
|
+
" via `attribute`."
|
239
|
+
end
|
264
240
|
|
265
|
-
|
241
|
+
subtype = subtype.subtype if EnumType === subtype
|
242
|
+
EnumType.new(name, enum_values, subtype, raise_on_invalid_values: !validate)
|
243
|
+
end
|
266
244
|
|
267
|
-
|
268
|
-
|
269
|
-
|
245
|
+
value_method_names = []
|
246
|
+
_enum_methods_module.module_eval do
|
247
|
+
prefix = if prefix
|
248
|
+
prefix == true ? "#{name}_" : "#{prefix}_"
|
270
249
|
end
|
271
250
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
prefix == true ? "#{name}_" : "#{prefix}_"
|
276
|
-
end
|
277
|
-
|
278
|
-
suffix = if suffix
|
279
|
-
suffix == true ? "_#{name}" : "_#{suffix}"
|
280
|
-
end
|
251
|
+
suffix = if suffix
|
252
|
+
suffix == true ? "_#{name}" : "_#{suffix}"
|
253
|
+
end
|
281
254
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
255
|
+
pairs = values.respond_to?(:each_pair) ? values.each_pair : values.each_with_index
|
256
|
+
pairs.each do |label, value|
|
257
|
+
enum_values[label] = value
|
258
|
+
label = label.to_s
|
286
259
|
|
287
|
-
|
288
|
-
|
289
|
-
|
260
|
+
value_method_name = "#{prefix}#{label}#{suffix}"
|
261
|
+
value_method_names << value_method_name
|
262
|
+
define_enum_methods(name, value_method_name, value, scopes, instance_methods)
|
290
263
|
|
291
|
-
|
292
|
-
|
264
|
+
method_friendly_label = label.gsub(/[\W&&[:ascii:]]+/, "_")
|
265
|
+
value_method_alias = "#{prefix}#{method_friendly_label}#{suffix}"
|
293
266
|
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
end
|
267
|
+
if value_method_alias != value_method_name && !value_method_names.include?(value_method_alias)
|
268
|
+
value_method_names << value_method_alias
|
269
|
+
define_enum_methods(name, value_method_alias, value, scopes, instance_methods)
|
298
270
|
end
|
299
271
|
end
|
300
|
-
|
272
|
+
end
|
273
|
+
detect_negative_enum_conditions!(value_method_names) if scopes
|
301
274
|
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
275
|
+
if validate
|
276
|
+
validate = {} unless Hash === validate
|
277
|
+
validates_inclusion_of name, in: enum_values.keys, **validate
|
278
|
+
end
|
279
|
+
|
280
|
+
enum_values.freeze
|
281
|
+
end
|
306
282
|
|
307
|
-
|
283
|
+
private
|
284
|
+
def inherited(base)
|
285
|
+
base.defined_enums = defined_enums.deep_dup
|
286
|
+
super
|
308
287
|
end
|
309
288
|
|
310
289
|
class EnumMethods < Module # :nodoc:
|
data/lib/active_record/errors.rb
CHANGED
@@ -84,6 +84,19 @@ module ActiveRecord
|
|
84
84
|
class ConnectionTimeoutError < ConnectionNotEstablished
|
85
85
|
end
|
86
86
|
|
87
|
+
# Raised when a database connection pool is requested but
|
88
|
+
# has not been defined.
|
89
|
+
class ConnectionNotDefined < ConnectionNotEstablished
|
90
|
+
def initialize(message = nil, connection_name: nil, role: nil, shard: nil)
|
91
|
+
super(message)
|
92
|
+
@connection_name = connection_name
|
93
|
+
@role = role
|
94
|
+
@shard = shard
|
95
|
+
end
|
96
|
+
|
97
|
+
attr_reader :connection_name, :role, :shard
|
98
|
+
end
|
99
|
+
|
87
100
|
# Raised when connection to the database could not been established because it was not
|
88
101
|
# able to connect to the host or when the authorization failed.
|
89
102
|
class DatabaseConnectionError < ConnectionNotEstablished
|
@@ -484,11 +497,6 @@ module ActiveRecord
|
|
484
497
|
# relation.limit!(5) # => ActiveRecord::UnmodifiableRelation
|
485
498
|
class UnmodifiableRelation < ActiveRecordError
|
486
499
|
end
|
487
|
-
deprecate_constant(
|
488
|
-
:ImmutableRelation,
|
489
|
-
"ActiveRecord::UnmodifiableRelation",
|
490
|
-
deprecator: ActiveRecord.deprecator
|
491
|
-
)
|
492
500
|
|
493
501
|
# TransactionIsolationError will be raised under the following conditions:
|
494
502
|
#
|
@@ -100,17 +100,21 @@ module ActiveRecord
|
|
100
100
|
def execute_or_skip
|
101
101
|
return unless pending?
|
102
102
|
|
103
|
-
@
|
104
|
-
return unless
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
103
|
+
@session.synchronize do
|
104
|
+
return unless pending?
|
105
|
+
|
106
|
+
@pool.with_connection do |connection|
|
107
|
+
return unless @mutex.try_lock
|
108
|
+
begin
|
109
|
+
if pending?
|
110
|
+
@event_buffer = EventBuffer.new(self, @instrumenter)
|
111
|
+
connection.with_instrumenter(@event_buffer) do
|
112
|
+
execute_query(connection, async: true)
|
113
|
+
end
|
110
114
|
end
|
115
|
+
ensure
|
116
|
+
@mutex.unlock
|
111
117
|
end
|
112
|
-
ensure
|
113
|
-
@mutex.unlock
|
114
118
|
end
|
115
119
|
end
|
116
120
|
end
|
@@ -163,7 +167,7 @@ module ActiveRecord
|
|
163
167
|
end
|
164
168
|
|
165
169
|
def exec_query(connection, *args, **kwargs)
|
166
|
-
connection.
|
170
|
+
connection.raw_exec_query(*args, **kwargs)
|
167
171
|
end
|
168
172
|
|
169
173
|
class SelectAll < FutureResult # :nodoc:
|
@@ -240,7 +240,7 @@ module ActiveRecord
|
|
240
240
|
|
241
241
|
values_list = insert_all.map_key_with_value do |key, value|
|
242
242
|
next value if Arel::Nodes::SqlLiteral === value
|
243
|
-
|
243
|
+
types[key].serialize(types[key].cast(value))
|
244
244
|
end
|
245
245
|
|
246
246
|
connection.visitor.compile(Arel::Nodes::ValuesList.new(values_list))
|
@@ -9,7 +9,7 @@ module ActiveRecord
|
|
9
9
|
# it was opened, an ActiveRecord::StaleObjectError exception is thrown if that has occurred
|
10
10
|
# and the update is ignored.
|
11
11
|
#
|
12
|
-
# Check out
|
12
|
+
# Check out ActiveRecord::Locking::Pessimistic for an alternative.
|
13
13
|
#
|
14
14
|
# == Usage
|
15
15
|
#
|
@@ -126,18 +126,12 @@ module ActiveRecord
|
|
126
126
|
end
|
127
127
|
end
|
128
128
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
return frame if frame
|
134
|
-
end
|
135
|
-
nil
|
136
|
-
end
|
137
|
-
else
|
138
|
-
def query_source_location
|
139
|
-
backtrace_cleaner.clean(caller(1).lazy).first
|
129
|
+
def query_source_location
|
130
|
+
Thread.each_caller_location do |location|
|
131
|
+
frame = backtrace_cleaner.clean_frame(location)
|
132
|
+
return frame if frame
|
140
133
|
end
|
134
|
+
nil
|
141
135
|
end
|
142
136
|
|
143
137
|
def filter(name, value)
|
@@ -25,7 +25,10 @@ module ActiveRecord
|
|
25
25
|
payload = [attributes_for_database, new_record?]
|
26
26
|
|
27
27
|
cached_associations = self.class.reflect_on_all_associations.select do |reflection|
|
28
|
-
association_cached?(reflection.name)
|
28
|
+
if association_cached?(reflection.name)
|
29
|
+
association = association(reflection.name)
|
30
|
+
association.loaded? || association.target.present?
|
31
|
+
end
|
29
32
|
end
|
30
33
|
|
31
34
|
unless cached_associations.empty?
|
@@ -22,10 +22,12 @@ module ActiveRecord
|
|
22
22
|
# * change_table_comment (must supply a +:from+ and +:to+ option)
|
23
23
|
# * create_enum
|
24
24
|
# * create_join_table
|
25
|
+
# * create_virtual_table
|
25
26
|
# * create_table
|
26
27
|
# * disable_extension
|
27
28
|
# * drop_enum (must supply a list of values)
|
28
29
|
# * drop_join_table
|
30
|
+
# * drop_virtual_table (must supply options)
|
29
31
|
# * drop_table (must supply a block)
|
30
32
|
# * enable_extension
|
31
33
|
# * remove_column (must supply a type)
|
@@ -55,6 +57,8 @@ module ActiveRecord
|
|
55
57
|
:add_exclusion_constraint, :remove_exclusion_constraint,
|
56
58
|
:add_unique_constraint, :remove_unique_constraint,
|
57
59
|
:create_enum, :drop_enum, :rename_enum, :add_enum_value, :rename_enum_value,
|
60
|
+
:create_schema, :drop_schema,
|
61
|
+
:create_virtual_table, :drop_virtual_table
|
58
62
|
]
|
59
63
|
include JoinTable
|
60
64
|
|
@@ -163,7 +167,9 @@ module ActiveRecord
|
|
163
167
|
add_exclusion_constraint: :remove_exclusion_constraint,
|
164
168
|
add_unique_constraint: :remove_unique_constraint,
|
165
169
|
enable_extension: :disable_extension,
|
166
|
-
create_enum: :drop_enum
|
170
|
+
create_enum: :drop_enum,
|
171
|
+
create_schema: :drop_schema,
|
172
|
+
create_virtual_table: :drop_virtual_table
|
167
173
|
}.each do |cmd, inv|
|
168
174
|
[[inv, cmd], [cmd, inv]].uniq.each do |method, inverse|
|
169
175
|
class_eval <<-EOV, __FILE__, __LINE__ + 1
|
@@ -196,13 +202,18 @@ module ActiveRecord
|
|
196
202
|
end
|
197
203
|
|
198
204
|
def invert_drop_table(args, &block)
|
199
|
-
|
200
|
-
|
205
|
+
options = args.extract_options!
|
206
|
+
options.delete(:if_exists)
|
207
|
+
|
208
|
+
if args.size > 1
|
209
|
+
raise ActiveRecord::IrreversibleMigration, "To avoid mistakes, drop_table is only reversible if given a single table name."
|
201
210
|
end
|
202
|
-
|
211
|
+
|
212
|
+
if args.size == 1 && options == {} && block == nil
|
203
213
|
raise ActiveRecord::IrreversibleMigration, "To avoid mistakes, drop_table is only reversible if given options or a block (can be empty)."
|
204
214
|
end
|
205
|
-
|
215
|
+
|
216
|
+
super(args.push(options), &block)
|
206
217
|
end
|
207
218
|
|
208
219
|
def invert_rename_table(args)
|
@@ -372,6 +383,12 @@ module ActiveRecord
|
|
372
383
|
[:rename_enum_value, [type_name, from: options[:to], to: options[:from]]]
|
373
384
|
end
|
374
385
|
|
386
|
+
def invert_drop_virtual_table(args)
|
387
|
+
_enum, values = args.dup.tap(&:extract_options!)
|
388
|
+
raise ActiveRecord::IrreversibleMigration, "drop_virtual_table is only reversible if given options." unless values
|
389
|
+
super
|
390
|
+
end
|
391
|
+
|
375
392
|
def respond_to_missing?(method, _)
|
376
393
|
super || delegate.respond_to?(method)
|
377
394
|
end
|
@@ -21,7 +21,7 @@ module ActiveRecord
|
|
21
21
|
# New migration functionality that will never be backward compatible should be added directly to `ActiveRecord::Migration`.
|
22
22
|
#
|
23
23
|
# There are classes for each prior Rails version. Each class descends from the *next* Rails version, so:
|
24
|
-
# 5.2 < 6.0 < 6.1 < 7.0 < 7.1 < 7.2
|
24
|
+
# 5.2 < 6.0 < 6.1 < 7.0 < 7.1 < 7.2 < 8.0
|
25
25
|
#
|
26
26
|
# If you are introducing new migration functionality that should only apply from Rails 7 onward, then you should
|
27
27
|
# find the class that immediately precedes it (6.1), and override the relevant migration methods to undo your changes.
|
@@ -29,7 +29,10 @@ module ActiveRecord
|
|
29
29
|
# For example, Rails 6 added a default value for the `precision` option on datetime columns. So in this file, the `V5_2`
|
30
30
|
# class sets the value of `precision` to `nil` if it's not explicitly provided. This way, the default value will not apply
|
31
31
|
# for migrations written for 5.2, but will for migrations written for 6.0.
|
32
|
-
|
32
|
+
V8_0 = Current
|
33
|
+
|
34
|
+
class V7_2 < V8_0
|
35
|
+
end
|
33
36
|
|
34
37
|
class V7_1 < V7_2
|
35
38
|
end
|