I'm following the Phoenix Guide on Plugs to create my own Module Plug
that loads the current user from session. The @user
is not being assigned when the Plug Module is used, but works fine when I call it as a private function within router.ex
.
This is my web/router
:
defmodule MyApp.Router do
use MyApp.Web, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug MyApp.Plugs.User
end
# Scopes and Routes...
end
This is my Module (in web/plugs/user.ex
):
defmodule MyApp.Plugs.User do
import Plug.Conn
def init(default), do: default
def call(conn, default) do
user = %{
id: get_session(conn, :user_id),
username: get_session(conn, :username)
}
assign(conn, :user, user)
IO.inspect conn
end
end
I tried inspecting it to see if it really was being assigned, but it wasn't:
%Plug.Conn{adapter: {Plug.Adapters.Cowboy.Conn, :...}, assigns: %{},
before_send: [#Function<1.75757453/1 in Plug.CSRFProtection.call/2>,
#Function<1.30521811/1 in Phoenix.Controller.fetch_flash/2>,
#Function<0.39713025/1 in Plug.Session.before_send/2>,
#Function<1.7608073/1 in Plug.Logger.call/2>,
#Function<0.72065156/1 in Phoenix.LiveReloader.before_send_inject_reloader/1>],
body_params: %{},
cookies: ....
Plug.Conn.assign
returns a modified connection. Since all data in Elixir is immutable it's not possible to modify the old one. In your case you're throwing away the result ofassign
and conn still points to the old connection. You probably want something like:This will rebind the
conn
variable to point to the modified connection structure. Of course it would also work ifassign(conn, :user, user)
would be the last expression in your function since its result would be returned.