I’m trying to implement a new version of an invite system. The plan is, for now, to leave the old route open for users who may have the previous version of the invite, while opening up a new route for the new invite style.
Presently the definition looks like this:
scope "/clubs/invite/", ClubWeb.Accounts, as: :club do
pipe_through [:browser]
get "/:token", InvitationController, :new
post "/:token", InvitationController, :create
get "/:uuid", UserInviteController, :new
post "/:uuid", UserInviteController, :create
end
When I saved, I saw a warning for each uuid line, referring to each token line before it:
warning: this clause cannot match because a previous clause at line xxx always matches
I have to admit, that confuses me a bit. Are these not different routes?
Nope - the :token / :uuid segments are your keywords for what’s captured in params, not a fixed part of the path. So you’ve specified GET and POST versions of a single route, /clubs/invite/[segment]. The final segment of the requested path will be captured as :token, with the uuid variants never reached during the matching operation.
I guess the best bet would be to create a new scope with a different path for the new api version. I’m new to elixir/phoenix though so perhaps someone else will chime in on the most elegant approach.
There is no way the system can understand if You pass a token or an uuid. Therefore :uuid will never be matched because the :token clause will match first.
You could try
get "/invitations/:token", InvitationController, :new
get "/user_invitations/:uuid", UserInviteController, :new