In Phoenix, get the function named path (or route) created by the Router Macro in the Controller

A lot of information can be gathered from the Controller using little-used functions like:

Phoenix.Controller.current_path(conn),

Phoenix.Router.route_info(
conn.private[:phoenix_router],
conn.method,
conn.request_path,
conn.host
),

Phoenix.Controller.action_name(conn), or

__ENV__.function()

But I do not find one that gives me the path function created by the Router. Is there a way to get it back?. For example, given:
"/api/v1/pages/:id"
get
api_v1_page_path
or
Routes.api_v1_page_path
or
{Routes, :api_v1_page_path, arity_something}

Thanks in advance.

hey dude

mix phx.routes

will print out all the routes your endpoints created :slight_smile:

live_dashboard_path  GET     /dashboard                             Phoenix.LiveView.Plug :home
live_dashboard_path  GET     /dashboard/:page                       Phoenix.LiveView.Plug :page
live_dashboard_path  GET     /dashboard/:node/:page                 Phoenix.LiveView.Plug :page
          websocket  WS      /live/websocket                        Phoenix.LiveView.Socket
           longpoll  GET     /live/longpoll                         Phoenix.LiveView.Socket
           longpoll  POST    /live/longpoll                         Phoenix.LiveView.Socket

First one is the path that you should pass to your link function.

It is always {controller_name}_path unless you use as in the endpoints so you don’t have to run the routes every time :slight_smile:

Hi @cenotaph, thanks for your reply. What I’m trying to do is a little different. I want to grab (or capture) at runtime the {controller_name}_path name function that the Router previously created at compile time. I other words, inside my controller use “something” to capture

{Routes, :{controller_name}_path, arity}

Note the second element in the Tuple is an atom.

The closest result so far is using Phoenix.Controller.current_path(conn) --obviuosly if I’m inside of the Controller Module I can call it directly, in other words just current_path(conn). Another approach is to use

Phoenix.Router.route_info(
  conn.private[:phoenix_router],
  conn.method,
  conn.request_path,
  conn.host
)

but I can only grab the route key that is the almost that It is close but not cigar. Anyway, I need what I shown in the example,
Given:

  • "/api/v1/pages/:id"

Get

  • api_v1_page_path

Note the deleted s, and :id, maybe (the conversion from string to atom) and the use of _ instead of / in the Get

ah sorry

you already had the method dude.

https://hexdocs.pm/phoenix/Phoenix.Router.html#route_info/4

Phoenix.Router.route_info(AppWeb.Router, "GET", "/posts/123", "myhost")
%{
  log: :debug,
  path_params: %{"id" => "123"},
  pipe_through: [:browser],
  plug: AppWeb.PostController,
  plug_opts: :show,
  route: "/posts/:id",
}

https://hexdocs.pm/phoenix/Phoenix.Router.html#scope/2

The generated route above will match on the path "/api/v1/pages/:id" and will dispatch to :show action in API.V1.PageController . A named helper api_v1_page_path will also be generated.

Hi @cenotaph, Almost there… the only part that I need is what you mention at the end

A named helper api_v1_page_path will also be generated.

Just the api_v1_page_path

1 Like