From e8efaca23ce0b5aa347dfa053091d0b48e746fb8 Mon Sep 17 00:00:00 2001
From: Yorick Peterse <yorickpeterse@gmail.com>
Date: Mon, 9 May 2016 15:05:19 +0200
Subject: [PATCH] Updated migration styleguide for new helpers

---
 doc/development/migration_style_guide.md | 46 ++++++++++++++++++++++--
 1 file changed, 44 insertions(+), 2 deletions(-)

diff --git a/doc/development/migration_style_guide.md b/doc/development/migration_style_guide.md
index 28dedf3978c..1c13b094582 100644
--- a/doc/development/migration_style_guide.md
+++ b/doc/development/migration_style_guide.md
@@ -8,7 +8,10 @@ In addition, having to take a server offline for a an upgrade small or big is
 a big burden for most organizations. For this reason it is important that your
 migrations are written carefully, can be applied online and adhere to the style guide below.
 
-It's advised to have offline migrations only in major GitLab releases.
+Migrations should not require GitLab installations to be taken offline unless
+_absolutely_ necessary. If a migration requires downtime this should be
+clearly mentioned during the review process as well as being documented in the
+monthly release post.
 
 When writing your migrations, also consider that databases might have stale data
 or inconsistencies and guard for that. Try to make as little assumptions as possible
@@ -58,6 +61,45 @@ remove_index :namespaces, column: :name if index_exists?(:namespaces, :name)
 
 If you need to add an unique index please keep in mind there is possibility of existing duplicates. If it is possible write a separate migration for handling this situation. It can be just removing or removing with overwriting all references to these duplicates depend on situation.
 
+When adding an index make sure to use the method `add_concurrent_index` instead
+of the regular `add_index` method. The `add_concurrent_index` method
+automatically creates concurrent indexes when using PostgreSQL, removing the
+need for downtime. To use this method you must disable transactions by calling
+the method `disable_ddl_transaction!` in the body of your migration class like
+so:
+
+```
+class MyMigration < ActiveRecord::Migration
+  disable_ddl_transaction!
+
+  def change
+
+  end
+end
+```
+
+## Adding Columns With Default Values
+
+When adding columns with default values you should use the method
+`add_column_with_default`. This method ensures the table is updated without
+requiring downtime. This method is not reversible so you must manually define
+the `up` and `down` methods in your migration class.
+
+For example, to add the column `foo` to the `projects` table with a default
+value of `10` you'd write the following:
+
+```
+class MyMigration < ActiveRecord::Migration
+  def up
+    add_column_with_default(:projects, :foo, :integer, 10)
+  end
+
+  def down
+    remove_column(:projects, :foo)
+  end
+end
+```
+
 ## Testing
 
 Make sure that your migration works with MySQL and PostgreSQL with data. An empty database does not guarantee that your migration is correct.
@@ -89,4 +131,4 @@ select_all("SELECT name, COUNT(id) as cnt FROM tags GROUP BY name HAVING COUNT(i
   execute("UPDATE taggings SET tag_id = #{origin_tag_id} WHERE tag_id IN(#{duplicate_ids.join(",")})")
   execute("DELETE FROM tags WHERE id IN(#{duplicate_ids.join(",")})")
 end
-```
\ No newline at end of file
+```
-- 
GitLab