Haito
Haito

Reputation: 2069

Injecting data into Phoenix's Action params

I'm trying to write some plugs to reduce amount of unneeded code in project and I would love to take some session data and put it into _params in controller's actions. But I have no idea how to do it. I came across the functon assign/3 but as far as i know it assigns data to be used in templates.

def logged(conn, _opts) do
    case get_session(conn, :login) do
      nil -> conn
        |> Phoenix.Controller.put_flash(:error, "Musisz być zalogowany")
        |> Phoenix.Controller.redirect( to: "/")
        |> Plug.Conn.halt
      login -> #here
    end
  end

And i want to be able to do:

def someaction(conn, %{"login" => login}) do
  #do something with login
end

Upvotes: 3

Views: 3310

Answers (1)

Gazler
Gazler

Reputation: 84140

There are two places where you can store key value pairs on a Plug.Conn struct. assigns and private. Generally you should use assigns for your application and private for libraries.

This storage is meant to be used by libraries and frameworks to avoid writing to the user storage (the :assigns field). It is recommended for libraries/frameworks to prefix the keys with the library name.

Using assign got your user:

def logged(conn, _opts) do
    case get_session(conn, :login) do
      nil -> conn
        ...
      login -> Plug.Conn.assign(conn, :current_user, login)
    end
  end

def someaction(conn, _params) do
  # do something with conn.assigns.current_user
end

If you use the current_user in your controller functions frequently then consider overriding the action/2 function in your controller. As documented in "Overriding action/2 for custom arguments" in the docs

def action(conn, _params) do
  apply(__MODULE__, action_name(conn), [conn, conn.params, conn.assigns.current_user)
end

def someaction(conn, _params, current_user) do
  # do something with current_user
end

For completeness. You can update the params (I wouldn't in the case of user authentication) using Kernel.update_in/2 as conn.params is a map:

update_in(conn.params, fn (params) -> Map.put(params, :something, "value") end)

Upvotes: 9

Related Questions