Hi again @Chrichton!
So the Routes.user_confirmation_url/3
isn’t defined as such in your router. It’s defined under the hood of Phoenix by virtue of the user_confirmation_path
routes that were added to your router.ex
file by the Phoenix Auth generator. The function itself is passed as an argument to the Accounts.deliver_user_confirmation_instructions/3
function in the UserConfirmationController
controller. In that Accounts
function, the Routes.user_confirmation_url/3
is finally invoked to return the user confirmation URL, with the correct user token, to be rendered in the email sent to the user. I would trace the code flow in the Accounts.deliver_user_confirmation_instructions/3
to get a better understanding of how the Routes.user_confirmation_url/3
function is being used.
Re: your exercise solution:
It looks like your solution will ensure that a user is redirected to the "/guess"
route when the complete the log in process. But the challenge is actually asking you to ensure that if a user who is logged in visits /
, that they get automatically redirected to /guess
. You can solve this a few different ways.
- Add a function plug to the
:browser
pipeline in therouter.ex
to redirect the user from/
to/guess
if they are logged in. Like this:
#router.ex
defmodule PentoWeb.Router do
use PentoWeb, :router
import Phoenix.Controller
...
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :put_root_layout, {PentoWeb.LayoutView, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
plug :fetch_current_user
plug :redirect_if_logged_in # add me!
end
...
def redirect_if_logged_in(conn, _opts) do
if conn.assigns.current_user && conn.request_path == "/" do
redirect(conn, to: "/guess")
end
conn
end
end
This requires importing the Phoenix.Controller
module into the router to get the redirect/2
function, which I don’t love.
You could also add some logic to the PageLive
live view’s mount
function to do a redirect if there is a logged in user. This is the live view that handles the /
route. It would look something like this:
# lib/pento_web/live/page_live.ex
def mount(_params, %{"user_token" => _}, socket) do
{:ok, redirect(socket, to: "/guess")}
end
def mount(_params, session, socket) do
{:ok, assign(socket, query: "", results: %{})}
end
Here, you are checking to see if there is a logged in user based on whether or not the session
argument given to mount
has a "user_token"key present. If so, there is a logged in user and you can use the
redirect` function to do a redirect.