From 96f19f6cf62fb4705a75cf4a81e4e2f145a4cee2 Mon Sep 17 00:00:00 2001 From: schneems Date: Tue, 5 Jun 2012 19:15:16 -0500 Subject: 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. --- activerecord/lib/active_record/migration.rb | 28 ++++++++++++++++++++++++++-- activerecord/lib/active_record/railtie.rb | 7 +++++++ activerecord/test/cases/migration_test.rb | 4 ++-- 3 files changed, 35 insertions(+), 4 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb index 2975b045e7..a0169203b0 100644 --- a/activerecord/lib/active_record/migration.rb +++ b/activerecord/lib/active_record/migration.rb @@ -32,6 +32,12 @@ module ActiveRecord 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 @@ module ActiveRecord 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 @@ module ActiveRecord end end - def needs_migration? - current_version != last_version + def needs_migrations? + current_version < last_version end def last_version diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb index 1e497b2a79..319516413b 100644 --- a/activerecord/lib/active_record/railtie.rb +++ b/activerecord/lib/active_record/railtie.rb @@ -59,6 +59,13 @@ module ActiveRecord 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) diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 45c847bae8..33d146dac3 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -63,12 +63,12 @@ class MigrationTest < ActiveRecord::TestCase 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 -- cgit v1.2.3