Can a route ignore inherited prefix for its own path helper?

Hi,

I’d like to ignore the inherited prefix from Phoenix.Router.resources and Phoenix.Router.scope when I define a route for its own generated path/url helpers (because they are injected by a macro). Is it possible? How could I achieve this?

For example:

scope "/foo", as: :foo do
  resources "/bar", MyAppWeb.BarController, only: ~W[new create]a, as: :name
end

Will generate the helper foo_name_path but I’d like to get name_path instead, by ignoring/getting rid of the inherited foo part (to be clear: in my real case, I can’t change the as, scope is defined by the user but resources is injected by a macro). Maybe my approach is inadequate? Have I miss some point in Phoenix.Router’s documentation?

Many thanks if you have a solution or a lead.

Hello!

The scope is all about grouping routes with a common prefix and plugs. So by adding as: :foo you’re saying you want all routes within the block to be prefixed by foo_.

You can, however, duplicate the scope block and not add the as: :foo.

scope "/foo", as: :foo do
  # other routes that requires the foo_ prefix
  resources "/other", MyAppWeb.OtherController
end

scope "/foo" do
  # keep /foo in the URL but don't prefix this route
  resources "/bar", MyAppWeb.BarController, only: ~W[new create]a, as: :name
end

Edit:
Oops, looks like I missed an important point where the user defines the scope but you want to inject routes using a macro.
After going through the docs again looks like you can’t do exactly what you want without the user duplicating the scope.

Thanks for your answer.

After going through the docs again looks like you can’t do exactly what you want without the user duplicating the scope.

Yeah, that’s what I wished to avoid.

Hi,

a follow up after reading this other topic How to shorten a too long phoenix router path helper name?

Enclosing the injected routes in a “dummy” scope as: false, alias: false doend block seems to do the trick since as: false resets route’s prefix name.

From my initial example:

scope "/foo", as: :foo do
  # <injected by a macro>
  scope as: false, alias: false do
    resources "/bar", MyAppWeb.BarController, only: ~W[new create]a, as: :name
  end
  # </injected by a macro>
end

The generated route will have /foo/bar as HTTP path (path is still inherited from outer scopes) and the _path function will be named name_path as wished.

1 Like