Repository: elixir-ecto/ecto
Pull request #2352 (2017-12-19 18:49:32)

Add `migration_default_prefix` to repo config
When you are working with a database that *always* uses an alternate
schema prefix to `public`, allow setting a default for all migrations
to use. From the model standpoint its easy to set @schema_prefix in a
module then use that module in your models, from the migration
perspective you have to remember to run migrations with `--prefix` or
set the prefix on each DDL statement which is prone to forgetfulness :D

The default is overridable at the DDL level by specifying
`prefix: "foo"` on a create table, index, or drop statement.

It is also overridable by passing `--prefix NAME` to the runner.

ebert[bot]: Hello, @coryodaniel! This is your first Pull Request that will be reviewed by [Ebert](https://ebertapp.io/), an automatic Code Review service. It will leave comments on this diff with potential issues and style violations found in the code as you push new commits. You can also see all the issues found on this Pull Request on its [review page](https://ebertapp.io/github/elixir-ecto/ecto/pulls/2352). Please check our [documentation](https://docs.ebertapp.io) for more information. 
ebert[bot]: Ebert has finished reviewing this Pull Request and has found:

* 1 possible new issue (including those that may have been commented here).

You can see more details about this review at https://ebertapp.io/github/elixir-ecto/ecto/pulls/2352.

<!-- Ebert auto generated comment -->


Patch:
diff --git a/lib/ecto/migration.ex b/lib/ecto/migration.ex
index 55824959..175c8dd6 100644
--- a/lib/ecto/migration.ex
+++ b/lib/ecto/migration.ex
@@ -174,6 +174,11 @@ defmodule Ecto.Migration do
 
           config :app, App.Repo, migration_lock: nil
 
+    * `:migration_default_prefix` - Ecto defaults to `nil` for the database prefix for
+      migrations but you can configure it via:
+
+          config :app, App.Repo, migration_default_prefix: "kewl"
+
   """
 
   defmodule Index do
@@ -921,11 +926,12 @@ defmodule Ecto.Migration do
 
   @doc false
   def __prefix__(%{prefix: prefix} = index_or_table) do
+    default_prefix = Runner.repo_config(:migration_default_prefix, nil)
     runner_prefix = Runner.prefix()
 
     cond do
       is_nil(prefix) ->
-        %{index_or_table | prefix: runner_prefix}
+        %{index_or_table | prefix: (runner_prefix || default_prefix)}
       is_nil(runner_prefix) or runner_prefix == to_string(prefix) ->
         index_or_table
       true ->


Test patch:
diff --git a/test/ecto/migration_test.exs b/test/ecto/migration_test.exs
index 67a8257e..ef7b2cb8 100644
--- a/test/ecto/migration_test.exs
+++ b/test/ecto/migration_test.exs
@@ -343,6 +343,33 @@ defmodule Ecto.MigrationTest do
     assert table.prefix == "foo"
   end
 
+  @tag prefix: "foo", repo_config: [migration_default_prefix: "baz"]
+  test "forward: creates a table with prefix from manager overriding the default prefix configuration" do
+    create(table(:posts))
+    flush()
+
+    {_, table, _} = last_command()
+    assert table.prefix == "foo"
+  end
+
+  @tag repo_config: [migration_default_prefix: "baz"]
+  test "forward: creates a table with prefix from migration overriding the default prefix configuration" do
+    create(table(:posts, prefix: "foo"))
+    flush()
+
+    {_, table, _} = last_command()
+    assert table.prefix == "foo"
+  end  
+
+  @tag repo_config: [migration_default_prefix: "baz"]
+  test "forward: create a table with prefix from configuration" do
+    create(table(:posts))
+    flush()
+
+    {_, table, _} = last_command()
+    assert table.prefix == "baz"
+  end
+
   @tag prefix: :foo
   test "forward: creates a table with prefix from manager matching atom prefix" do
     create(table(:posts, prefix: "foo"))
@@ -385,6 +412,14 @@ defmodule Ecto.MigrationTest do
     assert table.prefix == "foo"
   end
 
+  @tag repo_config: [migration_default_prefix: "baz"]
+  test "forward: drops a table with prefix from configuration" do
+    drop(table(:posts))
+    flush()
+    {:drop, table} = last_command()
+    assert table.prefix == "baz"
+  end
+
   test "forward: rename column on table with index prefixed from migration" do
     rename(table(:posts, prefix: "foo"), :given_name, to: :first_name)
     flush()
@@ -404,6 +439,16 @@ defmodule Ecto.MigrationTest do
     assert new_name == :first_name
   end
 
+  @tag repo_config: [migration_default_prefix: "baz"]
+  test "forward: rename column on table with index prefixed from configuration" do
+    rename(table(:posts), :given_name, to: :first_name)
+    flush()
+
+    {_, table, _, new_name} = last_command()
+    assert table.prefix == "baz"
+    assert new_name == :first_name
+  end
+
   test "forward: creates an index with prefix from migration" do
     create index(:posts, [:title], prefix: "foo")
     flush()
@@ -419,6 +464,14 @@ defmodule Ecto.MigrationTest do
     assert index.prefix == "foo"
   end
 
+  @tag repo_config: [migration_default_prefix: "baz"]
+  test "forward: creates an index with prefix from configuration" do
+    create index(:posts, [:title])
+    flush()
+    {_, index} = last_command()
+    assert index.prefix == "baz"
+  end
+
   test "forward: drops an index with a prefix from migration" do
     drop index(:posts, [:title], prefix: "foo")
     flush()
@@ -434,6 +487,14 @@ defmodule Ecto.MigrationTest do
     assert index.prefix == "foo"
   end
 
+  @tag repo_config: [migration_default_prefix: "baz"]
+  test "forward: drops an index with a prefix from configuration" do
+    drop index(:posts, [:title])
+    flush()
+    {_, index} = last_command()
+    assert index.prefix == "baz"
+  end
+
   test "forward: executes a command" do
     execute "SELECT 1", "SELECT 2"
     flush()