mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge pull request #45324 from adrianna-chang-shopify/ac-migration-strategy-objects
Introduce "Execution Strategy" object for Migrations
This commit is contained in:
commit
d51b171849
6 changed files with 81 additions and 2 deletions
|
@ -1,3 +1,11 @@
|
|||
* Introduce strategy pattern for executing migrations.
|
||||
|
||||
By default, migrations will use a strategy object that delegates the method
|
||||
to the connection adapter. Consumers can implement custom strategy objects
|
||||
to change how their migrations run.
|
||||
|
||||
*Adrianna Chang*
|
||||
|
||||
* Add adapter option disallowing foreign keys
|
||||
|
||||
This adds a new option to be added to `database.yml` which enables skipping
|
||||
|
|
|
@ -302,6 +302,12 @@ module ActiveRecord
|
|||
singleton_class.attr_accessor :timestamped_migrations
|
||||
self.timestamped_migrations = true
|
||||
|
||||
##
|
||||
# :singleton-method:
|
||||
# Specify strategy to use for executing migrations.
|
||||
singleton_class.attr_accessor :migration_strategy
|
||||
self.migration_strategy = Migration::DefaultStrategy
|
||||
|
||||
##
|
||||
# :singleton-method:
|
||||
# Specify whether schema dump should happen at the end of the
|
||||
|
|
|
@ -548,6 +548,8 @@ module ActiveRecord
|
|||
autoload :CommandRecorder, "active_record/migration/command_recorder"
|
||||
autoload :Compatibility, "active_record/migration/compatibility"
|
||||
autoload :JoinTable, "active_record/migration/join_table"
|
||||
autoload :ExecutionStrategy, "active_record/migration/execution_strategy"
|
||||
autoload :DefaultStrategy, "active_record/migration/default_strategy"
|
||||
|
||||
# This must be defined before the inherited hook, below
|
||||
class Current < Migration # :nodoc:
|
||||
|
@ -694,6 +696,10 @@ module ActiveRecord
|
|||
@connection = nil
|
||||
end
|
||||
|
||||
def execution_strategy
|
||||
@execution_strategy ||= ActiveRecord.migration_strategy.new(self)
|
||||
end
|
||||
|
||||
self.verbose = true
|
||||
# instantiate the delegate object after initialize is defined
|
||||
self.delegate = new
|
||||
|
@ -881,6 +887,7 @@ module ActiveRecord
|
|||
end
|
||||
ensure
|
||||
@connection = nil
|
||||
@execution_strategy = nil
|
||||
end
|
||||
|
||||
def write(text = "")
|
||||
|
@ -935,8 +942,8 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
end
|
||||
return super unless connection.respond_to?(method)
|
||||
connection.send(method, *arguments, &block)
|
||||
return super unless execution_strategy.respond_to?(method)
|
||||
execution_strategy.send(method, *arguments, &block)
|
||||
end
|
||||
end
|
||||
ruby2_keywords(:method_missing)
|
||||
|
|
23
activerecord/lib/active_record/migration/default_strategy.rb
Normal file
23
activerecord/lib/active_record/migration/default_strategy.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActiveRecord
|
||||
class Migration
|
||||
# The default strategy for executing migrations. Delegates method calls
|
||||
# to the connection adapter.
|
||||
class DefaultStrategy < ExecutionStrategy # :nodoc:
|
||||
private
|
||||
def method_missing(method, *arguments, &block)
|
||||
connection.send(method, *arguments, &block)
|
||||
end
|
||||
ruby2_keywords(:method_missing)
|
||||
|
||||
def respond_to_missing?(method, *)
|
||||
connection.respond_to?(method) || super
|
||||
end
|
||||
|
||||
def connection
|
||||
migration.connection
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActiveRecord
|
||||
class Migration
|
||||
# ExecutionStrategy is used by the migration to respond to any method calls
|
||||
# that the migration class does not implement directly. This is the base strategy.
|
||||
# All strategies should inherit from this class.
|
||||
#
|
||||
# The ExecutionStrategy receives the current +migration+ when initialized.
|
||||
class ExecutionStrategy # :nodoc:
|
||||
def initialize(migration)
|
||||
@migration = migration
|
||||
end
|
||||
|
||||
private
|
||||
attr_reader :migration
|
||||
end
|
||||
end
|
||||
end
|
|
@ -767,6 +767,22 @@ Specifies if an error should be raised if the order of a query is ignored during
|
|||
|
||||
Controls whether migrations are numbered with serial integers or with timestamps. The default is `true`, to use timestamps, which are preferred if there are multiple developers working on the same application.
|
||||
|
||||
#### `config.active_record.migration_strategy`
|
||||
|
||||
Controls the strategy class used to perform schema statement methods in a migration. The default class
|
||||
delegates to the connection adapter. Custom strategies should inherit from `ActiveRecord::Migration::ExecutionStrategy`,
|
||||
or may inherit from `DefaultStrategy`, which will preserve the default behaviour for methods that aren't implemented:
|
||||
|
||||
```ruby
|
||||
class CustomMigrationStrategy < ActiveRecord::Migration::DefaultStrategy
|
||||
def drop_table(*)
|
||||
raise "Dropping tables is not supported!"
|
||||
end
|
||||
end
|
||||
|
||||
config.active_record.migration_strategy = CustomMigrationStrategy
|
||||
```
|
||||
|
||||
#### `config.active_record.lock_optimistically`
|
||||
|
||||
Controls whether Active Record will use optimistic locking and is `true` by default.
|
||||
|
|
Loading…
Reference in a new issue