activerecord 7.2.2.1 → 8.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +523 -677
- data/README.rdoc +2 -2
- data/lib/active_record/association_relation.rb +1 -0
- data/lib/active_record/associations/alias_tracker.rb +6 -4
- data/lib/active_record/associations/association.rb +34 -10
- data/lib/active_record/associations/belongs_to_association.rb +18 -2
- 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 +3 -2
- data/lib/active_record/associations/join_dependency/join_association.rb +25 -27
- data/lib/active_record/associations/join_dependency.rb +2 -2
- data/lib/active_record/associations/preloader/association.rb +2 -2
- data/lib/active_record/associations/preloader/batch.rb +7 -1
- 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_methods/primary_key.rb +4 -8
- data/lib/active_record/attribute_methods/query.rb +34 -0
- data/lib/active_record/attribute_methods/serialization.rb +1 -1
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +2 -12
- data/lib/active_record/attribute_methods.rb +24 -19
- data/lib/active_record/attributes.rb +37 -26
- data/lib/active_record/autosave_association.rb +91 -39
- data/lib/active_record/base.rb +2 -2
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +34 -25
- 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 +55 -47
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +91 -44
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +25 -8
- 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 +12 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +40 -10
- data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -5
- data/lib/active_record/connection_adapters/abstract_adapter.rb +92 -70
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +35 -46
- data/lib/active_record/connection_adapters/mysql/quoting.rb +7 -9
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +2 -8
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +50 -45
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +84 -94
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +9 -9
- data/lib/active_record/connection_adapters/pool_config.rb +7 -7
- data/lib/active_record/connection_adapters/postgresql/column.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +72 -43
- data/lib/active_record/connection_adapters/postgresql/oid/array.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 +1 -11
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +20 -24
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +3 -2
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +60 -17
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +61 -99
- data/lib/active_record/connection_adapters/schema_cache.rb +1 -3
- data/lib/active_record/connection_adapters/sqlite3/column.rb +8 -2
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +80 -100
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +13 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +0 -6
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +27 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +10 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +63 -17
- data/lib/active_record/connection_adapters/statement_pool.rb +4 -2
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +37 -67
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +1 -18
- data/lib/active_record/connection_adapters.rb +0 -56
- data/lib/active_record/connection_handling.rb +35 -9
- data/lib/active_record/core.rb +57 -22
- data/lib/active_record/counter_cache.rb +1 -1
- data/lib/active_record/database_configurations/connection_url_resolver.rb +3 -1
- data/lib/active_record/database_configurations/database_config.rb +4 -0
- data/lib/active_record/database_configurations/hash_config.rb +16 -2
- data/lib/active_record/delegated_type.rb +18 -18
- data/lib/active_record/encryption/config.rb +3 -1
- data/lib/active_record/encryption/encryptable_record.rb +5 -5
- data/lib/active_record/encryption/encrypted_attribute_type.rb +11 -2
- data/lib/active_record/encryption/encryptor.rb +37 -28
- data/lib/active_record/encryption/extended_deterministic_queries.rb +4 -2
- data/lib/active_record/encryption/scheme.rb +8 -1
- data/lib/active_record/enum.rb +22 -34
- data/lib/active_record/errors.rb +16 -8
- data/lib/active_record/fixture_set/table_row.rb +19 -2
- data/lib/active_record/fixtures.rb +0 -2
- data/lib/active_record/future_result.rb +15 -9
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/insert_all.rb +3 -3
- data/lib/active_record/locking/optimistic.rb +1 -1
- data/lib/active_record/log_subscriber.rb +5 -11
- data/lib/active_record/migration/command_recorder.rb +32 -12
- data/lib/active_record/migration/compatibility.rb +5 -2
- data/lib/active_record/migration.rb +40 -43
- data/lib/active_record/model_schema.rb +3 -4
- data/lib/active_record/nested_attributes.rb +4 -6
- data/lib/active_record/persistence.rb +128 -130
- data/lib/active_record/query_logs.rb +106 -50
- data/lib/active_record/query_logs_formatter.rb +17 -28
- data/lib/active_record/querying.rb +12 -12
- data/lib/active_record/railtie.rb +4 -28
- data/lib/active_record/railties/databases.rake +11 -34
- data/lib/active_record/reflection.rb +18 -21
- 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 +71 -65
- data/lib/active_record/relation/delegation.rb +25 -14
- data/lib/active_record/relation/finder_methods.rb +32 -31
- data/lib/active_record/relation/merger.rb +8 -8
- data/lib/active_record/relation/predicate_builder/array_handler.rb +3 -1
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +2 -0
- 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 +13 -0
- data/lib/active_record/relation/query_attribute.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +121 -70
- data/lib/active_record/relation/spawn_methods.rb +7 -7
- data/lib/active_record/relation/where_clause.rb +9 -3
- data/lib/active_record/relation.rb +95 -67
- data/lib/active_record/result.rb +66 -4
- data/lib/active_record/sanitization.rb +7 -6
- data/lib/active_record/schema_dumper.rb +34 -11
- data/lib/active_record/schema_migration.rb +2 -1
- data/lib/active_record/scoping/named.rb +5 -2
- data/lib/active_record/secure_token.rb +3 -3
- data/lib/active_record/signed_id.rb +7 -6
- data/lib/active_record/statement_cache.rb +14 -14
- 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 +69 -60
- data/lib/active_record/tasks/mysql_database_tasks.rb +0 -2
- data/lib/active_record/tasks/postgresql_database_tasks.rb +9 -1
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -2
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +12 -0
- data/lib/active_record/token_for.rb +1 -1
- data/lib/active_record/transactions.rb +8 -7
- data/lib/active_record/type/serialized.rb +5 -0
- data/lib/active_record/validations/uniqueness.rb +8 -8
- data/lib/active_record.rb +22 -49
- data/lib/arel/collectors/bind.rb +2 -2
- data/lib/arel/collectors/sql_string.rb +1 -1
- data/lib/arel/collectors/substitute_binds.rb +2 -2
- data/lib/arel/crud.rb +2 -0
- data/lib/arel/delete_manager.rb +5 -0
- data/lib/arel/nodes/binary.rb +1 -1
- data/lib/arel/nodes/delete_statement.rb +4 -2
- data/lib/arel/nodes/node.rb +1 -1
- data/lib/arel/nodes/sql_literal.rb +1 -1
- data/lib/arel/nodes/update_statement.rb +4 -2
- data/lib/arel/predications.rb +1 -3
- data/lib/arel/select_manager.rb +6 -2
- data/lib/arel/table.rb +3 -7
- data/lib/arel/update_manager.rb +5 -0
- data/lib/arel/visitors/dot.rb +2 -0
- data/lib/arel/visitors/to_sql.rb +3 -1
- metadata +11 -15
- data/lib/active_record/relation/record_fetch_warning.rb +0 -52
data/lib/active_record/enum.rb
CHANGED
|
@@ -119,7 +119,18 @@ module ActiveRecord
|
|
|
119
119
|
# enum :status, [ :active, :archived ], instance_methods: false
|
|
120
120
|
# end
|
|
121
121
|
#
|
|
122
|
-
#
|
|
122
|
+
# By default, an +ArgumentError+ will be raised when assigning an invalid value:
|
|
123
|
+
#
|
|
124
|
+
# class Conversation < ActiveRecord::Base
|
|
125
|
+
# enum :status, [ :active, :archived ]
|
|
126
|
+
# end
|
|
127
|
+
#
|
|
128
|
+
# conversation = Conversation.new
|
|
129
|
+
#
|
|
130
|
+
# conversation.status = :unknown # 'unknown' is not a valid status (ArgumentError)
|
|
131
|
+
#
|
|
132
|
+
# If, instead, you want the enum value to be validated before saving, use the
|
|
133
|
+
# +:validate+ option:
|
|
123
134
|
#
|
|
124
135
|
# class Conversation < ActiveRecord::Base
|
|
125
136
|
# enum :status, [ :active, :archived ], validate: true
|
|
@@ -136,7 +147,7 @@ module ActiveRecord
|
|
|
136
147
|
# conversation.status = :active
|
|
137
148
|
# conversation.valid? # => true
|
|
138
149
|
#
|
|
139
|
-
#
|
|
150
|
+
# You may also pass additional validation options:
|
|
140
151
|
#
|
|
141
152
|
# class Conversation < ActiveRecord::Base
|
|
142
153
|
# enum :status, [ :active, :archived ], validate: { allow_nil: true }
|
|
@@ -152,16 +163,6 @@ module ActiveRecord
|
|
|
152
163
|
#
|
|
153
164
|
# conversation.status = :active
|
|
154
165
|
# conversation.valid? # => true
|
|
155
|
-
#
|
|
156
|
-
# Otherwise +ArgumentError+ will raise:
|
|
157
|
-
#
|
|
158
|
-
# class Conversation < ActiveRecord::Base
|
|
159
|
-
# enum :status, [ :active, :archived ]
|
|
160
|
-
# end
|
|
161
|
-
#
|
|
162
|
-
# conversation = Conversation.new
|
|
163
|
-
#
|
|
164
|
-
# conversation.status = :unknown # 'unknown' is not a valid status (ArgumentError)
|
|
165
166
|
module Enum
|
|
166
167
|
def self.extended(base) # :nodoc:
|
|
167
168
|
base.class_attribute(:defined_enums, instance_writer: false, default: {})
|
|
@@ -213,34 +214,16 @@ module ActiveRecord
|
|
|
213
214
|
attr_reader :name, :mapping
|
|
214
215
|
end
|
|
215
216
|
|
|
216
|
-
def enum(name
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
return _enum(name, values, **options)
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
definitions = options.slice!(:_prefix, :_suffix, :_scopes, :_default, :_instance_methods)
|
|
223
|
-
options.transform_keys! { |key| :"#{key[1..-1]}" }
|
|
224
|
-
|
|
225
|
-
definitions.each { |name, values| _enum(name, values, **options) }
|
|
226
|
-
|
|
227
|
-
ActiveRecord.deprecator.warn(<<~MSG)
|
|
228
|
-
Defining enums with keyword arguments is deprecated and will be removed
|
|
229
|
-
in Rails 8.0. Positional arguments should be used instead:
|
|
230
|
-
|
|
231
|
-
#{definitions.map { |name, values| "enum :#{name}, #{values}" }.join("\n")}
|
|
232
|
-
MSG
|
|
217
|
+
def enum(name, values = nil, **options)
|
|
218
|
+
values, options = options, {} unless values
|
|
219
|
+
_enum(name, values, **options)
|
|
233
220
|
end
|
|
234
221
|
|
|
235
222
|
private
|
|
236
|
-
def inherited(base)
|
|
237
|
-
base.defined_enums = defined_enums.deep_dup
|
|
238
|
-
super
|
|
239
|
-
end
|
|
240
|
-
|
|
241
223
|
def _enum(name, values, prefix: nil, suffix: nil, scopes: true, instance_methods: true, validate: false, **options)
|
|
242
224
|
assert_valid_enum_definition_values(values)
|
|
243
225
|
assert_valid_enum_options(options)
|
|
226
|
+
|
|
244
227
|
# statuses = { }
|
|
245
228
|
enum_values = ActiveSupport::HashWithIndifferentAccess.new
|
|
246
229
|
name = name.to_s
|
|
@@ -304,6 +287,11 @@ module ActiveRecord
|
|
|
304
287
|
enum_values.freeze
|
|
305
288
|
end
|
|
306
289
|
|
|
290
|
+
def inherited(base)
|
|
291
|
+
base.defined_enums = defined_enums.deep_dup
|
|
292
|
+
super
|
|
293
|
+
end
|
|
294
|
+
|
|
307
295
|
class EnumMethods < Module # :nodoc:
|
|
308
296
|
def initialize(klass)
|
|
309
297
|
@klass = klass
|
data/lib/active_record/errors.rb
CHANGED
|
@@ -13,7 +13,7 @@ module ActiveRecord
|
|
|
13
13
|
|
|
14
14
|
# Raised when the single-table inheritance mechanism fails to locate the subclass
|
|
15
15
|
# (for example due to improper usage of column that
|
|
16
|
-
# {ActiveRecord::Base.inheritance_column}[rdoc-ref:ModelSchema
|
|
16
|
+
# {ActiveRecord::Base.inheritance_column}[rdoc-ref:ModelSchema.inheritance_column]
|
|
17
17
|
# points to).
|
|
18
18
|
class SubclassNotFound < ActiveRecordError
|
|
19
19
|
end
|
|
@@ -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
|
|
@@ -431,7 +444,7 @@ module ActiveRecord
|
|
|
431
444
|
UnknownAttributeError = ActiveModel::UnknownAttributeError
|
|
432
445
|
|
|
433
446
|
# Raised when an error occurred while doing a mass assignment to an attribute through the
|
|
434
|
-
# {ActiveRecord::Base#attributes=}[rdoc-ref:AttributeAssignment#attributes=] method.
|
|
447
|
+
# {ActiveRecord::Base#attributes=}[rdoc-ref:ActiveModel::AttributeAssignment#attributes=] method.
|
|
435
448
|
# The exception has an +attribute+ property that is the name of the offending attribute.
|
|
436
449
|
class AttributeAssignmentError < ActiveRecordError
|
|
437
450
|
attr_reader :exception, :attribute
|
|
@@ -444,7 +457,7 @@ module ActiveRecord
|
|
|
444
457
|
end
|
|
445
458
|
|
|
446
459
|
# Raised when there are multiple errors while doing a mass assignment through the
|
|
447
|
-
# {ActiveRecord::Base#attributes=}[rdoc-ref:AttributeAssignment#attributes=]
|
|
460
|
+
# {ActiveRecord::Base#attributes=}[rdoc-ref:ActiveModel::AttributeAssignment#attributes=]
|
|
448
461
|
# method. The exception has an +errors+ property that contains an array of AttributeAssignmentError
|
|
449
462
|
# objects, each corresponding to the error while assigning to an attribute.
|
|
450
463
|
class MultiparameterAssignmentErrors < ActiveRecordError
|
|
@@ -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
|
#
|
|
@@ -193,8 +193,25 @@ module ActiveRecord
|
|
|
193
193
|
|
|
194
194
|
targets = targets.is_a?(Array) ? targets : targets.split(/\s*,\s*/)
|
|
195
195
|
joins = targets.map do |target|
|
|
196
|
-
join = {
|
|
197
|
-
|
|
196
|
+
join = {}
|
|
197
|
+
|
|
198
|
+
if rhs_key.is_a?(Array)
|
|
199
|
+
composite_key = ActiveRecord::FixtureSet.composite_identify(target, rhs_key)
|
|
200
|
+
composite_key.each do |column, value|
|
|
201
|
+
join[column] = value
|
|
202
|
+
end
|
|
203
|
+
else
|
|
204
|
+
join[rhs_key] = ActiveRecord::FixtureSet.identify(target, column_type)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
if lhs_key.is_a?(Array)
|
|
208
|
+
lhs_key.zip(model_metadata.primary_key_name).each do |fkey, pkey|
|
|
209
|
+
join[fkey] = @row[pkey]
|
|
210
|
+
end
|
|
211
|
+
else
|
|
212
|
+
join[lhs_key] = @row[model_metadata.primary_key_name]
|
|
213
|
+
end
|
|
214
|
+
|
|
198
215
|
association.timestamp_column_names.each do |col|
|
|
199
216
|
join[col] = @now
|
|
200
217
|
end
|
|
@@ -100,17 +100,23 @@ module ActiveRecord
|
|
|
100
100
|
def execute_or_skip
|
|
101
101
|
return unless pending?
|
|
102
102
|
|
|
103
|
-
@
|
|
104
|
-
return unless
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
103
|
+
@session.synchronize do
|
|
104
|
+
return unless pending?
|
|
105
|
+
|
|
106
|
+
@pool.with_connection do |connection|
|
|
107
|
+
return unless @mutex.try_lock
|
|
108
|
+
previous_instrumenter = ActiveSupport::IsolatedExecutionState[:active_record_instrumenter]
|
|
109
|
+
begin
|
|
110
|
+
if pending?
|
|
111
|
+
@event_buffer = EventBuffer.new(self, @instrumenter)
|
|
112
|
+
ActiveSupport::IsolatedExecutionState[:active_record_instrumenter] = @event_buffer
|
|
113
|
+
|
|
109
114
|
execute_query(connection, async: true)
|
|
110
115
|
end
|
|
116
|
+
ensure
|
|
117
|
+
ActiveSupport::IsolatedExecutionState[:active_record_instrumenter] = previous_instrumenter
|
|
118
|
+
@mutex.unlock
|
|
111
119
|
end
|
|
112
|
-
ensure
|
|
113
|
-
@mutex.unlock
|
|
114
120
|
end
|
|
115
121
|
end
|
|
116
122
|
end
|
|
@@ -163,7 +169,7 @@ module ActiveRecord
|
|
|
163
169
|
end
|
|
164
170
|
|
|
165
171
|
def exec_query(connection, *args, **kwargs)
|
|
166
|
-
connection.
|
|
172
|
+
connection.raw_exec_query(*args, **kwargs)
|
|
167
173
|
end
|
|
168
174
|
|
|
169
175
|
class SelectAll < FutureResult # :nodoc:
|
|
@@ -39,7 +39,7 @@ module ActiveRecord
|
|
|
39
39
|
@returning = (connection.supports_insert_returning? ? primary_keys : false) if @returning.nil?
|
|
40
40
|
@returning = false if @returning == []
|
|
41
41
|
|
|
42
|
-
@unique_by = find_unique_index_for(@unique_by)
|
|
42
|
+
@unique_by = find_unique_index_for(@unique_by) if @on_duplicate != :raise
|
|
43
43
|
|
|
44
44
|
configure_on_duplicate_update_logic
|
|
45
45
|
ensure_valid_options_for_connection!
|
|
@@ -48,7 +48,7 @@ module ActiveRecord
|
|
|
48
48
|
def execute
|
|
49
49
|
return ActiveRecord::Result.empty if inserts.empty?
|
|
50
50
|
|
|
51
|
-
message = +"#{model} "
|
|
51
|
+
message = +"#{model.name} "
|
|
52
52
|
message << "Bulk " if inserts.many?
|
|
53
53
|
message << (on_duplicate == :update ? "Upsert" : "Insert")
|
|
54
54
|
connection.exec_insert_all to_sql, message
|
|
@@ -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
|
+
ActiveModel::Type::SerializeCastValue.serialize(type = types[key], type.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)
|
|
@@ -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)
|
|
@@ -38,7 +40,7 @@ module ActiveRecord
|
|
|
38
40
|
# * remove_reference
|
|
39
41
|
# * remove_timestamps
|
|
40
42
|
# * rename_column
|
|
41
|
-
# * rename_enum
|
|
43
|
+
# * rename_enum
|
|
42
44
|
# * rename_enum_value (must supply a +:from+ and +:to+ option)
|
|
43
45
|
# * rename_index
|
|
44
46
|
# * rename_table
|
|
@@ -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
|
|
|
@@ -135,7 +139,7 @@ module ActiveRecord
|
|
|
135
139
|
recorder.reverting = @reverting
|
|
136
140
|
yield recorder.delegate.update_table_definition(table_name, recorder)
|
|
137
141
|
commands = recorder.commands
|
|
138
|
-
@commands << [:change_table, [table_name], -> t { bulk_change_table(
|
|
142
|
+
@commands << [:change_table, [table_name], -> t { bulk_change_table(t.name, commands.reverse) }]
|
|
139
143
|
else
|
|
140
144
|
yield delegate.update_table_definition(table_name, self)
|
|
141
145
|
end
|
|
@@ -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,20 @@ 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
|
+
args << options unless options.empty?
|
|
217
|
+
|
|
218
|
+
super(args, &block)
|
|
206
219
|
end
|
|
207
220
|
|
|
208
221
|
def invert_rename_table(args)
|
|
@@ -353,13 +366,13 @@ module ActiveRecord
|
|
|
353
366
|
end
|
|
354
367
|
|
|
355
368
|
def invert_rename_enum(args)
|
|
356
|
-
name,
|
|
369
|
+
name, new_name, = args
|
|
357
370
|
|
|
358
|
-
|
|
359
|
-
|
|
371
|
+
if new_name.is_a?(Hash) && new_name.key?(:to)
|
|
372
|
+
new_name = new_name[:to]
|
|
360
373
|
end
|
|
361
374
|
|
|
362
|
-
[:rename_enum, [
|
|
375
|
+
[:rename_enum, [new_name, name]]
|
|
363
376
|
end
|
|
364
377
|
|
|
365
378
|
def invert_rename_enum_value(args)
|
|
@@ -369,7 +382,14 @@ module ActiveRecord
|
|
|
369
382
|
raise ActiveRecord::IrreversibleMigration, "rename_enum_value is only reversible if given a :from and :to option."
|
|
370
383
|
end
|
|
371
384
|
|
|
372
|
-
[:
|
|
385
|
+
options[:to], options[:from] = options[:from], options[:to]
|
|
386
|
+
[:rename_enum_value, [type_name, options]]
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
def invert_drop_virtual_table(args)
|
|
390
|
+
_enum, values = args.dup.tap(&:extract_options!)
|
|
391
|
+
raise ActiveRecord::IrreversibleMigration, "drop_virtual_table is only reversible if given options." unless values
|
|
392
|
+
super
|
|
373
393
|
end
|
|
374
394
|
|
|
375
395
|
def respond_to_missing?(method, _)
|
|
@@ -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
|