Merge pull request #6665 from schneems/schneems/raise-migration-error
Notify A User they Have Pending Migrations
This commit is contained in:
commit
4845c0685a
|
@ -32,6 +32,12 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class PendingMigrationError < ActiveRecordError#:nodoc:
|
||||||
|
def initialize
|
||||||
|
super("Migrations are pending run 'bundle exec rake db:migrate RAILS_ENV=#{ENV['RAILS_ENV']}' to resolve the issue")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# = Active Record Migrations
|
# = Active Record Migrations
|
||||||
#
|
#
|
||||||
# Migrations can manage the evolution of a schema used by several physical
|
# Migrations can manage the evolution of a schema used by several physical
|
||||||
|
@ -326,10 +332,28 @@ module ActiveRecord
|
||||||
class Migration
|
class Migration
|
||||||
autoload :CommandRecorder, 'active_record/migration/command_recorder'
|
autoload :CommandRecorder, 'active_record/migration/command_recorder'
|
||||||
|
|
||||||
|
|
||||||
|
# This class is used to verify that all migrations have been run before
|
||||||
|
# loading a web page if config.active_record.migration_error is set to :page_load
|
||||||
|
class CheckPending
|
||||||
|
def initialize(app)
|
||||||
|
@app = app
|
||||||
|
end
|
||||||
|
|
||||||
|
def call(env)
|
||||||
|
ActiveRecord::Migration.check_pending!
|
||||||
|
status, headers, body = @app.call(env)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
attr_accessor :delegate # :nodoc:
|
attr_accessor :delegate # :nodoc:
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.check_pending!
|
||||||
|
raise ActiveRecord::PendingMigrationError if ActiveRecord::Migrator::needs_migrations?
|
||||||
|
end
|
||||||
|
|
||||||
def self.method_missing(name, *args, &block) # :nodoc:
|
def self.method_missing(name, *args, &block) # :nodoc:
|
||||||
(delegate || superclass.delegate).send(name, *args, &block)
|
(delegate || superclass.delegate).send(name, *args, &block)
|
||||||
end
|
end
|
||||||
|
@ -605,6 +629,14 @@ module ActiveRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def needs_migrations?
|
||||||
|
current_version < last_version
|
||||||
|
end
|
||||||
|
|
||||||
|
def last_version
|
||||||
|
migrations(migrations_paths).last.try(:version)||0
|
||||||
|
end
|
||||||
|
|
||||||
def proper_table_name(name)
|
def proper_table_name(name)
|
||||||
# Use the Active Record objects own table_name, or pre/suffix from ActiveRecord::Base if name is a symbol/string
|
# Use the Active Record objects own table_name, or pre/suffix from ActiveRecord::Base if name is a symbol/string
|
||||||
name.table_name rescue "#{ActiveRecord::Base.table_name_prefix}#{name}#{ActiveRecord::Base.table_name_suffix}"
|
name.table_name rescue "#{ActiveRecord::Base.table_name_prefix}#{name}#{ActiveRecord::Base.table_name_suffix}"
|
||||||
|
|
|
@ -59,6 +59,13 @@ module ActiveRecord
|
||||||
ActiveSupport.on_load(:active_record) { self.logger ||= ::Rails.logger }
|
ActiveSupport.on_load(:active_record) { self.logger ||= ::Rails.logger }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
initializer "active_record.migration_error" do |app|
|
||||||
|
if config.active_record.delete(:migration_error) == :page_load
|
||||||
|
config.app_middleware.insert_after "::ActionDispatch::Callbacks",
|
||||||
|
"ActiveRecord::Migration::CheckPending"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
initializer "active_record.set_configs" do |app|
|
initializer "active_record.set_configs" do |app|
|
||||||
ActiveSupport.on_load(:active_record) do
|
ActiveSupport.on_load(:active_record) do
|
||||||
if app.config.active_record.delete(:whitelist_attributes)
|
if app.config.active_record.delete(:whitelist_attributes)
|
||||||
|
|
|
@ -56,6 +56,21 @@ class MigrationTest < ActiveRecord::TestCase
|
||||||
Person.reset_column_information
|
Person.reset_column_information
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_migrator_versions
|
||||||
|
migrations_path = MIGRATIONS_ROOT + "/valid"
|
||||||
|
ActiveRecord::Migrator.migrations_paths = migrations_path
|
||||||
|
|
||||||
|
ActiveRecord::Migrator.up(migrations_path)
|
||||||
|
assert_equal 3, ActiveRecord::Migrator.current_version
|
||||||
|
assert_equal 3, ActiveRecord::Migrator.last_version
|
||||||
|
assert_equal false, ActiveRecord::Migrator.needs_migrations?
|
||||||
|
|
||||||
|
ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid")
|
||||||
|
assert_equal 0, ActiveRecord::Migrator.current_version
|
||||||
|
assert_equal 3, ActiveRecord::Migrator.last_version
|
||||||
|
assert_equal true, ActiveRecord::Migrator.needs_migrations?
|
||||||
|
end
|
||||||
|
|
||||||
def test_create_table_with_force_true_does_not_drop_nonexisting_table
|
def test_create_table_with_force_true_does_not_drop_nonexisting_table
|
||||||
if Person.connection.table_exists?(:testings2)
|
if Person.connection.table_exists?(:testings2)
|
||||||
Person.connection.drop_table :testings2
|
Person.connection.drop_table :testings2
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
# Log the query plan for queries taking more than this (works
|
# Log the query plan for queries taking more than this (works
|
||||||
# with SQLite, MySQL, and PostgreSQL).
|
# with SQLite, MySQL, and PostgreSQL).
|
||||||
config.active_record.auto_explain_threshold_in_seconds = 0.5
|
config.active_record.auto_explain_threshold_in_seconds = 0.5
|
||||||
|
|
||||||
|
# Raise an error on page load if there are pending migrations
|
||||||
|
config.active_record.migration_error = :page_load
|
||||||
<%- end -%>
|
<%- end -%>
|
||||||
|
|
||||||
<%- unless options.skip_sprockets? -%>
|
<%- unless options.skip_sprockets? -%>
|
||||||
|
|
|
@ -4,6 +4,8 @@ require 'rails/test_help'
|
||||||
|
|
||||||
class ActiveSupport::TestCase
|
class ActiveSupport::TestCase
|
||||||
<% unless options[:skip_active_record] -%>
|
<% unless options[:skip_active_record] -%>
|
||||||
|
ActiveRecord::Migration.check_pending!
|
||||||
|
|
||||||
# Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
|
# Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
|
||||||
#
|
#
|
||||||
# Note: You'll currently still have to declare fixtures explicitly in integration tests
|
# Note: You'll currently still have to declare fixtures explicitly in integration tests
|
||||||
|
|
|
@ -41,6 +41,21 @@ module ApplicationTests
|
||||||
FileUtils.rm_rf(new_app) if File.directory?(new_app)
|
FileUtils.rm_rf(new_app) if File.directory?(new_app)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "a renders exception on pending migration" do
|
||||||
|
add_to_config <<-RUBY
|
||||||
|
config.active_record.migration_error = :page_load
|
||||||
|
config.consider_all_requests_local = true
|
||||||
|
config.action_dispatch.show_exceptions = true
|
||||||
|
RUBY
|
||||||
|
|
||||||
|
require "#{app_path}/config/environment"
|
||||||
|
ActiveRecord::Migrator.stubs(:needs_migrations?).returns(true)
|
||||||
|
|
||||||
|
get "/foo"
|
||||||
|
assert_equal 500, last_response.status
|
||||||
|
assert_match "ActiveRecord::PendingMigrationError", last_response.body
|
||||||
|
end
|
||||||
|
|
||||||
test "multiple queue construction is possible" do
|
test "multiple queue construction is possible" do
|
||||||
require 'rails'
|
require 'rails'
|
||||||
require "#{app_path}/config/environment"
|
require "#{app_path}/config/environment"
|
||||||
|
|
Loading…
Reference in New Issue