Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

raise error for pending migration

can be configured by setting config.active_record.migration. Setting to :page_load will raise an error on each page refresh if there are migrations that are pending. Setting to :page_load is defaulted in development for new applications.
  • Loading branch information...
commit 96f19f6cf62fb4705a75cf4a81e4e2f145a4cee2 1 parent e5b3986
@schneems schneems authored
View
28 activerecord/lib/active_record/migration.rb
@@ -32,6 +32,12 @@ def initialize(name)
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
#
# Migrations can manage the evolution of a schema used by several physical
@@ -326,10 +332,28 @@ def initialize(name)
class Migration
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
attr_accessor :delegate # :nodoc:
end
+ def self.check_pending!
+ raise ActiveRecord::PendingMigrationError if ActiveRecord::Migrator::needs_migrations?
+ end
+
def self.method_missing(name, *args, &block) # :nodoc:
(delegate || superclass.delegate).send(name, *args, &block)
end
@@ -605,8 +629,8 @@ def current_version
end
end
- def needs_migration?
- current_version != last_version
+ def needs_migrations?
+ current_version < last_version
end
def last_version
View
7 activerecord/lib/active_record/railtie.rb
@@ -59,6 +59,13 @@ class Railtie < Rails::Railtie
ActiveSupport.on_load(:active_record) { self.logger ||= ::Rails.logger }
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|
ActiveSupport.on_load(:active_record) do
if app.config.active_record.delete(:whitelist_attributes)
View
4 activerecord/test/cases/migration_test.rb
@@ -63,12 +63,12 @@ def test_migrator_versions
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_migration?
+ 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_migration?
+ assert_equal true, ActiveRecord::Migrator.needs_migrations?
end
def test_create_table_with_force_true_does_not_drop_nonexisting_table
View
3  railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
@@ -26,6 +26,9 @@
# Log the query plan for queries taking more than this (works
# with SQLite, MySQL, and PostgreSQL).
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 -%>
<%- unless options.skip_sprockets? -%>
View
2  railties/lib/rails/generators/rails/app/templates/test/test_helper.rb
@@ -4,6 +4,8 @@
class ActiveSupport::TestCase
<% unless options[:skip_active_record] -%>
+ ActiveRecord::Migration.check_pending!
+
# 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
Please sign in to comment.
Something went wrong with that request. Please try again.