1
votes

I'm trying to create a button that makes a given user an admin. For that I'd like to create a route for the request post /users/:id/admin. In order to do that, I'm trying to create a nested resource like so:

resources "/users", UserController, only: [:new, :create, :index] do
  resources "/admin", UserController, only: [:post]
end

But when I run mix phx.routes | grep users, I only get those routes:

user_path  GET     /users            StorexWeb.UserController :index
user_path  GET     /users/new        StorexWeb.UserController :new
user_path  POST    /users            StorexWeb.UserController :create

As if the nested resource was not declared. What is wrong with my resource declaration ? and how can I fix it ?

3

3 Answers

5
votes

The issue is in only: [:post]. There is no such action :post, so you end-up with nothing. You probably wanted this:

resources "/users", UserController, only: [:new, :create, :index] do
  resources "/admin", UserController, only: [:create]
end

I will open up an issue in Phoenix to raise in those cases to avoid further confusion.

0
votes

With nested resources, that would be not a resource, but a scope. The following should work:

scope "/users" do
  resources "/", UserController, only: [:new, :create, :index]

  resources "/admin", UserController, only: [:post]
end
0
votes

For this scenario I prefer using post/get directly instead of using resources because I am not forced to use a specific function name such as create especially if the controller of your nested resource has only one endpoint/function (e.g. /users/admin with post).

resources "/users", UserController, only: [:new, :create, :index] do
  post "/admin", UserController, :post
end