I’m building an app in Phoenix 1.3 and I’m struggling with decisions related to contexts. Specifically, I don’t understand how user schemas in multiple contexts should interact with auth.
I’m using Guardian for authentication and overriding controller __action__
to pipe around my current_user
to my controller actions as an additional argument.
def new(conn, params, current_user) do
end
Above, current_user
is fetched from Guardian and loaded into assigns
using a router plug.
When I started writing the app I had one context, Accounts
, and current_user
was an %App.Accounts.User{}
struct.
+ app
+ accounts
- accounts.ex
- user.ex
- media.ex
My Accounts
context became bloated and I extracted a Registration
context to handle user registration as it has specific oauth logic useless elsewhere. Both user schemas use the same database table.
+ app
+ accounts
- accounts.ex
- user.ex
- media.ex
+ registration
- registration.ex
- user.ex
One side effect is the ability to log in as %Registration.User{}
or %Accounts.User{}
. The current_user
being piped to my controller actions from Guardian can be either struct, but they have different behaviours, associations, etc…
I wrote multiple function heads in guardian_serializer.ex
to deal with one situation where I need to log the user in before continuing with registration. It seems odd, though.
def for_token(user = %Accounts.User{}) do
{:ok, "AccountsUser:#{user.username}"}
end
def for_token(user = %Registration.User{}) do
{:ok, "RegistrationUser:#{user.username}"}
end
def from_token("AccountsUser:" <> username) do
{:ok, Repo.get_by(Accounts.User, username: username)}
end
def from_token("RegistrationUser:" <> username) do
{:ok, Repo.get_by(Registration.User, username: username)}
end
I imagine this will become more complicated as I add contexts. The current_user
being piped around needs to have the correct behaviour and associations to interact with the rest of the context. It doesn’t seem like multiple user structs go well with auth and multiple contexts.
What do you think?