diff options
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/CHANGELOG.md | 16 | ||||
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb | 8 | ||||
-rw-r--r-- | activerecord/lib/active_record/migration.rb | 24 | ||||
-rw-r--r-- | activerecord/lib/active_record/schema.rb | 40 | ||||
-rw-r--r-- | activerecord/lib/active_record/schema_dumper.rb | 21 | ||||
-rw-r--r-- | activerecord/lib/active_record/schema_migration.rb | 39 | ||||
-rw-r--r-- | activerecord/test/cases/ar_schema_test.rb | 51 | ||||
-rw-r--r-- | activerecord/test/cases/migration/logger_test.rb | 2 | ||||
-rw-r--r-- | activerecord/test/cases/migration/table_and_index_test.rb | 24 | ||||
-rw-r--r-- | activerecord/test/cases/migration_test.rb | 11 | ||||
-rw-r--r-- | activerecord/test/cases/migrator_test.rb | 9 | ||||
-rw-r--r-- | activerecord/test/cases/schema_dumper_test.rb | 17 | ||||
-rw-r--r-- | activerecord/test/cases/schema_migration_test.rb | 54 | ||||
-rw-r--r-- | activerecord/test/migrations/always_safe/1001_always_safe.rb | 5 | ||||
-rw-r--r-- | activerecord/test/migrations/always_safe/1002_still_safe.rb | 5 |
15 files changed, 60 insertions, 266 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index ab8c54e4cb..b1988172cb 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -46,22 +46,6 @@ *Chris Feist* -* Add migration history to `schema.rb` dump. Loading `schema.rb` with full migration - history restores the exact list of migrations that created that schema (including names - and fingerprints). This avoids possible mistakes caused by assuming all migrations with - a lower version have been run when loading `schema.rb`. Old `schema.rb` files without - migration history but with the `:version` setting still work as before. - - *Josh Susser* - -* Add metadata columns to `schema_migrations` table. New columns are: - - * `migrated_at`: timestamp - * `fingerprint`: md5 hash of migration source - * `name`: filename minus version and extension - - *Josh Susser* - * Fix performance problem with `primary_key` method in PostgreSQL adapter when having many schemas. Uses `pg_constraint` table instead of `pg_depend` table which has many records in general. Fix #8414 diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index 1586e84a25..f1e42dfbbe 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -490,8 +490,8 @@ module ActiveRecord sm_table = ActiveRecord::Migrator.schema_migrations_table_name ActiveRecord::SchemaMigration.order('version').map { |sm| - "INSERT INTO #{sm_table} (version, migrated_at, fingerprint, name) VALUES ('#{sm.version}',CURRENT_TIMESTAMP,'#{sm.fingerprint}','#{sm.name}');" - }.join("\n\n") + "INSERT INTO #{sm_table} (version) VALUES ('#{sm.version}');" + }.join "\n\n" end # Should not be called normally, but this operation is non-destructive. @@ -512,7 +512,7 @@ module ActiveRecord end unless migrated.include?(version) - ActiveRecord::SchemaMigration.create!(:version => version, :migrated_at => Time.now) + execute "INSERT INTO #{sm_table} (version) VALUES ('#{version}')" end inserted = Set.new @@ -520,7 +520,7 @@ module ActiveRecord if inserted.include?(v) raise "Duplicate migration #{v}. Please renumber your migrations to resolve the conflict." elsif v < version - ActiveRecord::SchemaMigration.create!(:version => v, :migrated_at => Time.now) + execute "INSERT INTO #{sm_table} (version) VALUES ('#{v}')" inserted << v end end diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb index 4ce276d4bf..22347fcaef 100644 --- a/activerecord/lib/active_record/migration.rb +++ b/activerecord/lib/active_record/migration.rb @@ -1,6 +1,5 @@ require "active_support/core_ext/class/attribute_accessors" require 'set' -require 'digest/md5' module ActiveRecord # Exception that can be raised to stop migrations from going backwards. @@ -555,10 +554,6 @@ module ActiveRecord delegate :migrate, :announce, :write, :to => :migration - def fingerprint - @fingerprint ||= Digest::MD5.hexdigest(File.read(filename)) - end - private def migration @@ -729,7 +724,7 @@ module ActiveRecord raise UnknownMigrationVersionError.new(@target_version) if target.nil? unless (up? && migrated.include?(target.version.to_i)) || (down? && !migrated.include?(target.version.to_i)) target.migrate(@direction) - record_version_state_after_migrating(target) + record_version_state_after_migrating(target.version) end end @@ -752,7 +747,7 @@ module ActiveRecord begin ddl_transaction do migration.migrate(@direction) - record_version_state_after_migrating(migration) + record_version_state_after_migrating(migration.version) end rescue => e canceled_msg = Base.connection.supports_ddl_transactions? ? "this and " : "" @@ -810,18 +805,13 @@ module ActiveRecord raise DuplicateMigrationVersionError.new(version) if version end - def record_version_state_after_migrating(target) + def record_version_state_after_migrating(version) if down? - migrated.delete(target.version) - ActiveRecord::SchemaMigration.where(:version => target.version.to_s).delete_all + migrated.delete(version) + ActiveRecord::SchemaMigration.where(:version => version.to_s).delete_all else - migrated << target.version - ActiveRecord::SchemaMigration.create!( - :version => target.version.to_s, - :migrated_at => Time.now, - :fingerprint => target.fingerprint, - :name => File.basename(target.filename,'.rb').gsub(/^\d+_/,'') - ) + migrated << version + ActiveRecord::SchemaMigration.create!(:version => version.to_s) end end diff --git a/activerecord/lib/active_record/schema.rb b/activerecord/lib/active_record/schema.rb index 44b7eb424b..3259dbbd80 100644 --- a/activerecord/lib/active_record/schema.rb +++ b/activerecord/lib/active_record/schema.rb @@ -39,45 +39,27 @@ module ActiveRecord end def define(info, &block) # :nodoc: - @using_deprecated_version_setting = info[:version].present? - SchemaMigration.drop_table - initialize_schema_migrations_table - instance_eval(&block) - # handle files from pre-4.0 that used :version option instead of dumping migration table - assume_migrated_upto_version(info[:version], migrations_paths) if @using_deprecated_version_setting + unless info[:version].blank? + initialize_schema_migrations_table + assume_migrated_upto_version(info[:version], migrations_paths) + end end # Eval the given block. All methods available to the current connection # adapter are available within the block, so you can easily use the # database definition DSL to build up your schema (+create_table+, # +add_index+, etc.). - def self.define(info={}, &block) - new.define(info, &block) - end - - # Create schema migration history. Include migration statements in a block to this method. - # - # migrations do - # migration 20121128235959, "44f1397e3b92442ca7488a029068a5ad", "add_horn_color_to_unicorns" - # migration 20121129235959, "4a1eb3965d94406b00002b370854eae8", "add_magic_power_to_unicorns" - # end - def migrations - raise(ArgumentError, "Can't set migrations while using :version option") if @using_deprecated_version_setting - yield - end - - # Add a migration to the ActiveRecord::SchemaMigration table. # - # The +version+ argument is an integer. - # The +fingerprint+ and +name+ arguments are required but may be empty strings. - # The migration's +migrated_at+ attribute is set to the current time, - # instead of being set explicitly as an argument to the method. + # The +info+ hash is optional, and if given is used to define metadata + # about the current schema (currently, only the schema's version): # - # migration 20121129235959, "4a1eb3965d94406b00002b370854eae8", "add_magic_power_to_unicorns" - def migration(version, fingerprint, name) - SchemaMigration.create!(version: version, migrated_at: Time.now, fingerprint: fingerprint, name: name) + # ActiveRecord::Schema.define(version: 20380119000001) do + # ... + # end + def self.define(info={}, &block) + new.define(info, &block) end end end diff --git a/activerecord/lib/active_record/schema_dumper.rb b/activerecord/lib/active_record/schema_dumper.rb index 194a77ca16..36bde44e7c 100644 --- a/activerecord/lib/active_record/schema_dumper.rb +++ b/activerecord/lib/active_record/schema_dumper.rb @@ -24,7 +24,6 @@ module ActiveRecord def dump(stream) header(stream) - migrations(stream) tables(stream) trailer(stream) stream @@ -39,11 +38,13 @@ module ActiveRecord end def header(stream) + define_params = @version ? "version: #{@version}" : "" + if stream.respond_to?(:external_encoding) && stream.external_encoding stream.puts "# encoding: #{stream.external_encoding.name}" end - header_text = <<HEADER_RUBY + stream.puts <<HEADER # This file is auto-generated from the current state of the database. Instead # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. @@ -56,27 +57,15 @@ module ActiveRecord # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define do +ActiveRecord::Schema.define(#{define_params}) do -HEADER_RUBY - stream.puts header_text +HEADER end def trailer(stream) stream.puts "end" end - def migrations(stream) - all_migrations = ActiveRecord::SchemaMigration.all.to_a - if all_migrations.any? - stream.puts(" migrations do") - all_migrations.each do |migration| - stream.puts(migration.schema_line(" ")) - end - stream.puts(" end\n\n") - end - end - def tables(stream) @connection.tables.sort.each do |tbl| next if ['schema_migrations', ignore_tables].flatten.any? do |ignored| diff --git a/activerecord/lib/active_record/schema_migration.rb b/activerecord/lib/active_record/schema_migration.rb index 6c3cd5b6ba..9830abe7d8 100644 --- a/activerecord/lib/active_record/schema_migration.rb +++ b/activerecord/lib/active_record/schema_migration.rb @@ -14,38 +14,17 @@ module ActiveRecord end def self.create_table - if connection.table_exists?(table_name) - cols = connection.columns(table_name).collect { |col| col.name } - unless cols.include?("migrated_at") - connection.add_column(table_name, "migrated_at", :datetime) - q_table_name = connection.quote_table_name(table_name) - q_timestamp = connection.quoted_date(Time.now) - connection.update("UPDATE #{q_table_name} SET migrated_at = '#{q_timestamp}' WHERE migrated_at IS NULL") - connection.change_column(table_name, "migrated_at", :datetime, :null => false) - end - unless cols.include?("fingerprint") - connection.add_column(table_name, "fingerprint", :string, :limit => 32) - end - unless cols.include?("name") - connection.add_column(table_name, "name", :string) - end - else + unless connection.table_exists?(table_name) connection.create_table(table_name, :id => false) do |t| t.column :version, :string, :null => false - t.column :migrated_at, :datetime, :null => false - t.column :fingerprint, :string, :limit => 32 - t.column :name, :string end - connection.add_index(table_name, "version", :unique => true, :name => index_name) + connection.add_index table_name, :version, :unique => true, :name => index_name end - reset_column_information end def self.drop_table if connection.table_exists?(table_name) - if connection.index_exists?(table_name, "version", :unique => true, :name => index_name) - connection.remove_index(table_name, :name => index_name) - end + connection.remove_index table_name, :name => index_name connection.drop_table(table_name) end end @@ -53,17 +32,5 @@ module ActiveRecord def version super.to_i end - - # Construct ruby source to include in schema.rb dump for this migration. - # Pass a string of spaces as +indent+ to allow calling code to control how deeply indented the line is. - # The generated line includes the migration version, fingerprint, and name. Either fingerprint or name - # can be an empty string. - # - # Example output: - # - # migration 20121129235959, "ee4be703f9e6e2fc0f4baddebe6eb8f7", "add_magic_power_to_unicorns" - def schema_line(indent) - %Q(#{indent}migration %s, "%s", "%s") % [version, fingerprint, name] - end end end diff --git a/activerecord/test/cases/ar_schema_test.rb b/activerecord/test/cases/ar_schema_test.rb index bd47ba8741..b2eac0349b 100644 --- a/activerecord/test/cases/ar_schema_test.rb +++ b/activerecord/test/cases/ar_schema_test.rb @@ -46,55 +46,4 @@ if ActiveRecord::Base.connection.supports_migrations? end end - class ActiveRecordSchemaMigrationsTest < ActiveRecordSchemaTest - def setup - super - ActiveRecord::SchemaMigration.delete_all - end - - def test_migration_adds_row_to_migrations_table - schema = ActiveRecord::Schema.new - schema.migration(1001, "", "") - schema.migration(1002, "123456789012345678901234567890ab", "add_magic_power_to_unicorns") - - migrations = ActiveRecord::SchemaMigration.all.to_a - assert_equal 2, migrations.length - - assert_equal 1001, migrations[0].version - assert_match %r{^2\d\d\d-}, migrations[0].migrated_at.to_s(:db) - assert_equal "", migrations[0].fingerprint - assert_equal "", migrations[0].name - - assert_equal 1002, migrations[1].version - assert_match %r{^2\d\d\d-}, migrations[1].migrated_at.to_s(:db) - assert_equal "123456789012345678901234567890ab", migrations[1].fingerprint - assert_equal "add_magic_power_to_unicorns", migrations[1].name - end - - def test_define_clears_schema_migrations - assert_nothing_raised do - ActiveRecord::Schema.define do - migrations do - migration(123001, "", "") - end - end - ActiveRecord::Schema.define do - migrations do - migration(123001, "", "") - end - end - end - end - - def test_define_raises_if_both_version_and_explicit_migrations - assert_raise(ArgumentError) do - ActiveRecord::Schema.define(version: 123001) do - migrations do - migration(123001, "", "") - end - end - end - end - end - end diff --git a/activerecord/test/cases/migration/logger_test.rb b/activerecord/test/cases/migration/logger_test.rb index c2fdc50e52..ee0c20747e 100644 --- a/activerecord/test/cases/migration/logger_test.rb +++ b/activerecord/test/cases/migration/logger_test.rb @@ -10,8 +10,6 @@ module ActiveRecord def migrate direction # do nothing end - def filename; "anon.rb"; end - def fingerprint; "123456789012345678901234567890ab"; end end def setup diff --git a/activerecord/test/cases/migration/table_and_index_test.rb b/activerecord/test/cases/migration/table_and_index_test.rb new file mode 100644 index 0000000000..8fd770abd1 --- /dev/null +++ b/activerecord/test/cases/migration/table_and_index_test.rb @@ -0,0 +1,24 @@ +require "cases/helper" + +module ActiveRecord + class Migration + class TableAndIndexTest < ActiveRecord::TestCase + def test_add_schema_info_respects_prefix_and_suffix + conn = ActiveRecord::Base.connection + + conn.drop_table(ActiveRecord::Migrator.schema_migrations_table_name) if conn.table_exists?(ActiveRecord::Migrator.schema_migrations_table_name) + # Use shorter prefix and suffix as in Oracle database identifier cannot be larger than 30 characters + ActiveRecord::Base.table_name_prefix = 'p_' + ActiveRecord::Base.table_name_suffix = '_s' + conn.drop_table(ActiveRecord::Migrator.schema_migrations_table_name) if conn.table_exists?(ActiveRecord::Migrator.schema_migrations_table_name) + + conn.initialize_schema_migrations_table + + assert_equal "p_unique_schema_migrations_s", conn.indexes(ActiveRecord::Migrator.schema_migrations_table_name)[0][:name] + ensure + ActiveRecord::Base.table_name_prefix = "" + ActiveRecord::Base.table_name_suffix = "" + end + end + end +end diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 3a861d887f..c155f29973 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -59,21 +59,12 @@ class MigrationTest < ActiveRecord::TestCase def test_migrator_versions migrations_path = MIGRATIONS_ROOT + "/valid" ActiveRecord::Migrator.migrations_paths = migrations_path - m0_path = File.join(migrations_path, "1_valid_people_have_last_names.rb") - m0_fingerprint = Digest::MD5.hexdigest(File.read(m0_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_migration? - rows = connection.select_all("SELECT * FROM #{connection.quote_table_name(ActiveRecord::Migrator.schema_migrations_table_name)}") - assert_equal m0_fingerprint, rows[0]["fingerprint"] - assert_equal "valid_people_have_last_names", rows[0]["name"] - rows.each do |row| - assert_match(/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/, row["migrated_at"].to_s, "missing migrated_at") # sometimes a String, sometimes a Time - end - ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid") assert_equal 0, ActiveRecord::Migrator.current_version assert_equal 3, ActiveRecord::Migrator.last_version @@ -346,7 +337,7 @@ class MigrationTest < ActiveRecord::TestCase assert_nothing_raised { Person.connection.create_table :binary_testings do |t| - t.column :data, :binary, :null => false + t.column "data", :binary, :null => false end } diff --git a/activerecord/test/cases/migrator_test.rb b/activerecord/test/cases/migrator_test.rb index 0f0384382f..1e16addcf3 100644 --- a/activerecord/test/cases/migrator_test.rb +++ b/activerecord/test/cases/migrator_test.rb @@ -18,9 +18,6 @@ module ActiveRecord def up; @went_up = true; end def down; @went_down = true; end - # also used in place of a MigrationProxy - def filename; "anon.rb"; end - def fingerprint; "123456789012345678901234567890ab"; end end def setup @@ -105,7 +102,7 @@ module ActiveRecord end def test_finds_pending_migrations - ActiveRecord::SchemaMigration.create!(:version => '1', :name => "anon", :migrated_at => Time.now) + ActiveRecord::SchemaMigration.create!(:version => '1') migration_list = [ Migration.new('foo', 1), Migration.new('bar', 3) ] migrations = ActiveRecord::Migrator.new(:up, migration_list).pending_migrations @@ -155,7 +152,7 @@ module ActiveRecord end def test_current_version - ActiveRecord::SchemaMigration.create!(:version => '1000', :name => "anon", :migrated_at => Time.now) + ActiveRecord::SchemaMigration.create!(:version => '1000') assert_equal 1000, ActiveRecord::Migrator.current_version end @@ -323,7 +320,7 @@ module ActiveRecord def test_only_loads_pending_migrations # migrate up to 1 - ActiveRecord::SchemaMigration.create!(:version => '1', :name => "anon", :migrated_at => Time.now) + ActiveRecord::SchemaMigration.create!(:version => '1') calls, migrator = migrator_class(3) migrator.migrate("valid", nil) diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb index 264846eedb..7ff0044bd4 100644 --- a/activerecord/test/cases/schema_dumper_test.rb +++ b/activerecord/test/cases/schema_dumper_test.rb @@ -1,5 +1,6 @@ require "cases/helper" + class SchemaDumperTest < ActiveRecord::TestCase def setup super @@ -17,15 +18,11 @@ class SchemaDumperTest < ActiveRecord::TestCase def test_dump_schema_information_outputs_lexically_ordered_versions versions = %w{ 20100101010101 20100201010101 20100301010101 } versions.reverse.each do |v| - ActiveRecord::SchemaMigration.create!( - :version => v, :migrated_at => Time.now, - :fingerprint => "123456789012345678901234567890ab", :name => "anon") + ActiveRecord::SchemaMigration.create!(:version => v) end schema_info = ActiveRecord::Base.connection.dump_schema_information assert_match(/20100201010101.*20100301010101/m, schema_info) - target_line = %q{INSERT INTO schema_migrations (version, migrated_at, fingerprint, name) VALUES ('20100101010101',CURRENT_TIMESTAMP,'123456789012345678901234567890ab','anon');} - assert_match target_line, schema_info end def test_magic_comment @@ -39,16 +36,6 @@ class SchemaDumperTest < ActiveRecord::TestCase assert_no_match %r{create_table "schema_migrations"}, output end - def test_schema_dump_includes_migrations - ActiveRecord::SchemaMigration.delete_all - ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/always_safe") - - output = standard_dump - assert_match %r{migrations do}, output, "Missing migrations block" - assert_match %r{migration 1001, "[0-9a-f]{32}", "always_safe"}, output, "Missing migration line" - assert_match %r{migration 1002, "[0-9a-f]{32}", "still_safe"}, output, "Missing migration line" - end - def test_schema_dump_excludes_sqlite_sequence output = standard_dump assert_no_match %r{create_table "sqlite_sequence"}, output diff --git a/activerecord/test/cases/schema_migration_test.rb b/activerecord/test/cases/schema_migration_test.rb deleted file mode 100644 index 882067a7d4..0000000000 --- a/activerecord/test/cases/schema_migration_test.rb +++ /dev/null @@ -1,54 +0,0 @@ -require "cases/helper" - -class SchemaMigrationTest < ActiveRecord::TestCase - def sm_table_name - ActiveRecord::SchemaMigration.table_name - end - - def connection - ActiveRecord::Base.connection - end - - def test_add_schema_info_respects_prefix_and_suffix - connection.drop_table(sm_table_name) if connection.table_exists?(sm_table_name) - # Use shorter prefix and suffix as in Oracle database identifier cannot be larger than 30 characters - ActiveRecord::Base.table_name_prefix = 'p_' - ActiveRecord::Base.table_name_suffix = '_s' - connection.drop_table(sm_table_name) if connection.table_exists?(sm_table_name) - - ActiveRecord::SchemaMigration.create_table - - assert_equal "p_unique_schema_migrations_s", connection.indexes(sm_table_name)[0][:name] - ensure - ActiveRecord::Base.table_name_prefix = "" - ActiveRecord::Base.table_name_suffix = "" - end - - def test_add_metadata_columns_to_exisiting_schema_migrations - # creates the old table schema from pre-Rails4.0, so we can test adding to it below - if connection.table_exists?(sm_table_name) - connection.drop_table(sm_table_name) - end - connection.create_table(sm_table_name, :id => false) do |schema_migrations_table| - schema_migrations_table.column("version", :string, :null => false) - end - - connection.insert "INSERT INTO #{connection.quote_table_name(sm_table_name)} (version) VALUES (100)" - connection.insert "INSERT INTO #{connection.quote_table_name(sm_table_name)} (version) VALUES (200)" - - ActiveRecord::SchemaMigration.create_table - - rows = connection.select_all("SELECT * FROM #{connection.quote_table_name(sm_table_name)}") - assert rows[0].has_key?("migrated_at"), "missing column `migrated_at`" - assert_match(/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/, rows[0]["migrated_at"].to_s) # sometimes a String, sometimes a Time - assert rows[0].has_key?("fingerprint"), "missing column `fingerprint`" - assert rows[0].has_key?("name"), "missing column `name`" - end - - def test_schema_migrations_columns - ActiveRecord::SchemaMigration.create_table - - columns = connection.columns(sm_table_name).collect(&:name) - %w[version migrated_at fingerprint name].each { |col| assert columns.include?(col), "missing column `#{col}`" } - end -end diff --git a/activerecord/test/migrations/always_safe/1001_always_safe.rb b/activerecord/test/migrations/always_safe/1001_always_safe.rb deleted file mode 100644 index 454b972507..0000000000 --- a/activerecord/test/migrations/always_safe/1001_always_safe.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AlwaysSafe < ActiveRecord::Migration - def change - # do nothing to avoid side-effect conflicts from running multiple times - end -end diff --git a/activerecord/test/migrations/always_safe/1002_still_safe.rb b/activerecord/test/migrations/always_safe/1002_still_safe.rb deleted file mode 100644 index 7398ae27a2..0000000000 --- a/activerecord/test/migrations/always_safe/1002_still_safe.rb +++ /dev/null @@ -1,5 +0,0 @@ -class StillSafe < ActiveRecord::Migration - def change - # do nothing to avoid side-effect conflicts from running multiple times - end -end |