我在/users/:user_id/...
下有几个嵌套路由,控制器需要user
。在所有这些控制器中,我有以下代码。但我不想在所有控制器中使用相同的代码,只能在一个地方使用。适合放置的地方在哪里?我该怎么干?
defmodule MyApp.XyzController do
use MyApp.Web, :controller
plug :assign_user
[...]
defp assign_user(conn, _opts) do
case conn.params do
%{"user_id" => user_id} ->
case Repo.get(MyApp.User, user_id) do
nil -> invalid_user(conn)
user -> assign(conn, :user, user)
end
_ -> invalid_user(conn)
end
end
defp invalid_user(conn) do
conn
|> put_flash(:error, "Invalid user!")
|> redirect(to: page_path(conn, :index))
|> halt
end
end
答案 0 :(得分:3)
您应该为此创建一个Plug。我通常将其放在lib/plugs/
或web/plugs/
中,文件名与模块的最后一部分相同(例如此插件的fetch_user.ex
)。
像(未经测试)的东西:
defmodule MyApp.Plugs.FetchUser do
import Plug.Conn
alias MyApp.Repo
def init(_) do
nil
end
def call(conn, _opts) do
case conn.params do
%{"user_id" => user_id} ->
case Repo.get(MyApp.User, user_id) do
nil -> invalid_user(conn)
user -> assign(conn, :user, user)
end
_ -> invalid_user(conn)
end
end
defp invalid_user(conn) do
conn
|> put_flash(:error, "Invalid user!")
|> redirect(to: page_path(conn, :index))
|> halt
end
end
然后在你的控制器中写下:
plug MyApp.Plugs.FetchUser