在 ex_admin 中添加控制器方法 (Phoenix)

Adding controller methods in ex_admin (Phoenix)

我正在使用 Phoenix 的 ex_admin 包。成功完成标准安装后,我创建了一个 User 资源,其中包含一个名称和一个头像(它将引用 S3 上的一个文件)

>> mix phoenix.gen.model User users name:string avatar:string

>> mix admin.gen.resource User

modules: [
    MyApp.ExAdmin.Dashboard,
    MyApp.ExAdmin.User
]

>> iex -S mix phoenix.server

效果很好。现在我想添加修改 create 函数的等价物,如果我使用 mix phoenix.gen.html User ... 创建资源,则该函数将存在于 web/controllers/user_controller.ex 中。然而,尽管后端正确地进行了 CRUD,但我找不到该特定资源的任何控制器。

解决这个问题的最佳方法是什么?创建一个 web/controllers/user_controller.ex 文件并覆盖它?将函数作为模块添加到其他地方?

您可以通过两种方式连接到 ExAdmin 中的控制器操作。

1.在控制器上添加 before_filterafter_filter

对于这种方法,请在资源文件中使用 controller 宏。

defmodule MyApp.ExAdmin.License do
  use ExAdmin.Register
  register_resource MyApp.License do
    # ...
    controller do
      before_filter :set_current_user, only: [:create, :update]
      before_filter :set_updated_by, only: [:update]

      def set_current_user(conn, params) do
        new_params = put_in(params, [:license, :user_id], MyApp.Authentication.current_user(conn).id)
        {conn, new_params}
      end
      def set_updated_by({conn, params}, _params) do
        new_params = put_in(params, [:license, :updated_by_id], MyApp.Authentication.current_user(conn).id)
        {conn, new_params}
      end
    end
  end
end

查看大师的文档here

2。创建你自己的控制器

使用这种方法,您可以创建一个控制器,其中包含您要覆盖的操作。要使用您的自定义控制器,您需要为所需的操作添加路由。只需确保您创建的路由位于路由器中的此块之上。

scope "/admin", ExAdmin do
  pipe_through :browser
  admin_routes
end

这是自定义控制器的示例。请注意,您需要包含 @resource "my_resource".

defmodule ExAdmin.ClientController do
  @resource "clients"
  use ExAdmin.Web, :resource_controller
  alias UcxRemote.{Client, Repo, ClientService}
  require Logger
  use Utils

  def create(conn, _defn, %{_format: "json", client: client_params} = _params) do
    result = do_create conn, client_params
    case result do
      {:ok, client} ->
        put_view(conn, UcxRemote.ApiClientView)
        |> render("create.json", client: client)
      {:error, _changeset} ->
        json conn, %{errors: ["Validation failed"]}
    end
  end

  def create(conn, defn, params) do
    result = do_create conn, params[:client]
    case result do
      {:ok, client} ->
        conn
        |> put_flash(:notice, "Client was successfully created.")
        |> redirect(to: admin_resource_path(client, :show))
      {:error, changeset} ->
        errors = get_errors(changeset, "creating")
        conn
        |> put_flash(:error, errors)
        |> handle_changeset_error(defn, changeset, params)
    end
  end

  defp do_create(conn, %{user_id: user_id} = client_params) do
    changeset = %Client{user_id: user_id}
    |> Repo.preload([user: :company])
    |> Client.changeset(client_params)
    Repo.insert(changeset)
  end
end

这是路线:

 scope "/", ExAdmin do
    pipe_through :browser
    post "/clients", ClientController, :create
 end