Help in constructing "controller" delete

I am currently trying to have my controller, identify whether in the is_admin column, would be true or false …

Below is my controller.

  def delete(conn, %{"id" => id}) do
   if @current_user.is_admin do
    project = Registro.get_project!(id)
    {:ok, _project} = Registro.delete_project(project)

    conn
    |> put_flash(:info, "Deleted successfully.")
    |> redirect(to: project_path(conn, :index))
   else
    conn
    |> put_flash(:info, "You do not have permission.")
   end
  end

But I get a mistake…

warning: undefined module attribute @current_user, please remove access to @current_user or explicitly set it before access
lib/project_web/controllers/project_controller.ex:82: ProjectWeb.ProjectController.delete/2

What would be wrong?

You need a way to know who is connecting. This @current_user cannot come from nowhere…

I usually send a token to the user. And this user use this token on each subsequent calls. That way, when I decode it, I get the user id, and use it to load user, and check if is_admin.

My bet is You are using session, so You should retrieve session variables… and use them to load user.

You don’t show what happens after connection, it’s hard to tell. I guess it must be in your login controller.

There is a difference on what the @identifier construct means in the template and in the module. In the Phoenix template, usage of @assign1 is just a shorthand for Map.get(assigns, :assign1). In Elixir, @something is a compile-time module attribute.

Thus, you can’t use @current_user in the controller. Probably you wanted to get it from conn.assigns.

1 Like

I made some changes …

Look how it was …

Controller

  def delete(conn, %{"id" => id, "@current_user.is_admin" => isAdmin}) do
    project = Registro.get_project!(id)
      if isAdmin do
    {:ok, _project} = Registro.delete_project(project)

    conn
    |> put_flash(:info, "Deleted successfully.")
    |> redirect(to: project_path(conn, :index))
   else
    conn
    |> put_flash(:info, "You are not allowed.")
   end
  end

template.
<span><%= link "Deletar", to: project_path(@conn, :delete, project, @current_user.is_admin), method: :delete, data: [confirm: "Are you sure?"], class: "btn btn-danger btn-xs" %></span>

Errors:

Using admin = true

could not find a matching ProjectWeb.ProjectController.delete clause to process request. This typically happens when there is a parameter mismatch but may also happen when any of the other action arguments do not match. The request parameters are:

Using default user = false

protocol Enumerable not implemented for false. This protocol is implemented for: DBConnection.PrepareStream, DBConnection.Stream, Date.Range, Ecto.Adapters.SQL.Stream, File.Stream, Function, GenEvent.Stream, HashDict, HashSet, IO.Stream, List, Map, MapSet, Range, Stream

If you are passing @current_users.is_admin in body or params of the request this will work but I am assuming this is not the case and current_user is being set by a plug or something…so it is going to end up in conn.assigns. Pattern match against conn.assigns if this is the case.

1 Like

def delete(%{“id” => id, assigns: %{current_user: %{“is_admin” => isAdmin}}} = conn, params) do
#stuff
end

something like this.

1 Like

With the help of @kokolegorille
I was able to solve,
adding a plug.
plug Guardian.Plug.EnsureAuthenticated, [handler: ControllerController].

Thank you all for help.