From df82237a45e930a7ab53b95bee78a3f34c5b92fb Mon Sep 17 00:00:00 2001 From: Rich Date: Tue, 14 Nov 2017 19:24:00 +0000 Subject: Add a #populate method to migrations (#31082) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add a #populate method to migrations * Address rubocop issues * Rename to #up_only and use #execute in the examples intead of the model * Update CHANGELOG [Rich Daley & Rafael Mendonça França] --- activerecord/CHANGELOG.md | 5 +++++ activerecord/lib/active_record/migration.rb | 18 ++++++++++++++++ .../test/cases/invertible_migration_test.rb | 25 ++++++++++++++++++++++ 3 files changed, 48 insertions(+) (limited to 'activerecord') diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 57ec37c75b..2088b018d7 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,8 @@ +* Add `#only_up` to database migrations for code that is only relevant when + migrating up, e.g. populating a new column. + + *Rich Daley* + * Require raw SQL fragments to be explicitly marked when used in relation query methods. diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb index c13efa9d70..67c8c9fc08 100644 --- a/activerecord/lib/active_record/migration.rb +++ b/activerecord/lib/active_record/migration.rb @@ -734,6 +734,24 @@ module ActiveRecord execute_block { yield helper } end + # Used to specify an operation that is only run when migrating up + # (for example, populating a new column with its initial values). + # + # In the following example, the new column `published` will be given + # the value `true` for all existing records. + # + # class AddPublishedToPosts < ActiveRecord::Migration[5.3] + # def change + # add_column :posts, :published, :boolean, default: false + # up_only do + # execute "update posts set published = 'true'" + # end + # end + # end + def up_only + execute_block { yield } unless reverting? + end + # Runs the given migration classes. # Last argument can specify options: # - :direction (default is :up) diff --git a/activerecord/test/cases/invertible_migration_test.rb b/activerecord/test/cases/invertible_migration_test.rb index 60c628511f..e0f40710eb 100644 --- a/activerecord/test/cases/invertible_migration_test.rb +++ b/activerecord/test/cases/invertible_migration_test.rb @@ -161,6 +161,13 @@ module ActiveRecord end end + class UpOnlyMigration < SilentMigration + def change + add_column :horses, :oldie, :boolean, default: false + up_only { execute "update horses set oldie = 'true'" } + end + end + setup do @verbose_was, ActiveRecord::Migration.verbose = ActiveRecord::Migration.verbose, false end @@ -378,5 +385,23 @@ module ActiveRecord "horses_index_named index should not exist" end end + + def test_up_only + InvertibleMigration.new.migrate(:up) + horse1 = Horse.create + # populates existing horses with oldie=true but new ones have default false + UpOnlyMigration.new.migrate(:up) + Horse.reset_column_information + horse1.reload + horse2 = Horse.create + + assert horse1.oldie? # created before migration + assert !horse2.oldie? # created after migration + + UpOnlyMigration.new.migrate(:down) # should be no error + connection = ActiveRecord::Base.connection + assert !connection.column_exists?(:horses, :oldie) + Horse.reset_column_information + end end end -- cgit v1.2.3