Reputation: 2674
I am working with the ex_admin package for Phoenix. After doing a successful standard install, I create a User
resource with a name and an avatar (which will reference a file on 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
Works great. Now I'd like to add modify the equivalent of the create
function that would exist in web/controllers/user_controller.ex
if I had made the resource with mix phoenix.gen.html User ...
. However, despite the fact that the backend is CRUD'ing properly, I can't find any controllers for this specific resource.
What is the best way to tackle this? Create a web/controllers/user_controller.ex
file and have it override? Add the function as a module elsewhere?
Upvotes: 1
Views: 369
Reputation: 4507
There two ways you can hook into controller actions in ExAdmin.
1. Add either a before_filter
or an after_filter
on the controller.
For this approach, use the controller
macro in your resource file.
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
Checkout the docs from master here
2. Create you own controller
With this approach, you create a controller with the actions you want to override. To use your custom controller, you will need to add routes for the desired actions. Just make sure the routes you create are above this block in your router.
scope "/admin", ExAdmin do
pipe_through :browser
admin_routes
end
Here is an example of a custom controller. Note that you need to include the @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
Here is the route:
scope "/", ExAdmin do
pipe_through :browser
post "/clients", ClientController, :create
end
Upvotes: 1