Phoenix -控制器和视图之间的回调动作



我正在为我们的系统构建一个管理工具应用程序。我想记录每个用户的每一个动作

我是这么做的

defmodule AdminToolWeb.UserController do
use AdminToolWeb, :controller

...
def delete(conn, %{"id" => id}) do
current_user = Guardian.Plug.current_resource(conn)
with %User{} <- user = Accounts.get_user(id) do
Accounts.delete_user(user)
conn
|> put_flash(:info, "#{user.id} deleted.")
|> Activities.log(current_user)
|> redirect(to: Routes.user_path(conn, :index))
end
end
...
end

问题是我必须在我的应用程序中的每个控制器的每个动作中管道|> Activity.log(current_user)

有办法实现这样的东西吗?Controller -> (ActivityLogPlugOfSorts) -> View用一个定制插头,然后这样叫它?

defmodule AdminToolWeb.UserController do
use AdminToolWeb, :controller
import AdminToolWeb.Plugs.Activities
plug :log
...

但是它应该在控制器和视图之间调用

或者我应该把一个函数内的视图模块代替?

我希望有更好的方法。

你在这里寻找的是控制器插头,它确实可以直接插入控制器级别。它们将在之前运行控制器动作,因此当插头运行时,您将没有机会知道尝试的动作是否成功。然而,你可以使用控制器插头来设置一个回调,它将在之后运行。控制器动作(但在发送响应之前)。例如:

defmodule HelloWeb.Plugs.ActionLogger do
import Plug.Conn
require Logger
def init(default), do: default
def call(conn, _default) do
register_before_send(conn, fn conn ->
if (response_code_2xx?(conn) do
Logger.info("action taken: #{extract_action(conn)}")
end
conn
end)
end
end

其中response_code_2xx?/1extract_action/1留作习题,供读者参考。

最新更新