如何回滚特定的外迁移?

How to rollback a specific ecto migration?

Phoenix 相当于 Rails' 是什么?

rake db:migrate:down VERSION=20100905201547

目前有 no way to accomplish this.

我们可以使用以下方法一直回滚到特定迁移:

mix ecto.rollback -v 20080906120000

mix ecto.rollback --to 20080906120000

但是对于这两种语法,当前语法和指定语法之间的所有迁移也将被回滚。

Elixir Forum 中的一位用户还提到,创建一个新的迁移将撤消需要撤消的内容,这将是保持历史可访问性的好方法。

这应该可以解决问题:

def rollback(version) when is_integer(version) do
  re = ~r/^#{version}_.*\.exs/
  path = Application.app_dir(:your_app, Path.join(["priv", "repo", "migrations"]))

  with {:find, "" <> file} <- {:find, Enum.find(File.ls!(path), &String.match?(&1, re))},
        {:compile, [{mod, _} | _]} <- {:compile, Code.compile_file(Path.join(path, file))},
        {:rollback, :ok} <- {:rollback, Ecto.Migrator.down(Repo, version, mod)} do
    {:ok, "Reversed migration: #{file}"}
  else
    {:find, _} -> {:error, "No migration found with version prefix: #{version}"}
    {:compile, e} -> {:error, "Problem compiling migration module: #{inspect(e)}"}
    {:rollback, e} -> {:error, "Problem reversing migration: #{inspect(e)}"}
    e -> {:error, "Something unexpected happened: #{inspect(e)}"}
  end
end