Luiz E.
Luiz E.

Reputation: 7279

routes with wrong params

I have the following route:

resources :users, only: [] do
  resources :events, only: %i[index]
  delete :close_account, on: :member
end

for some reason, it generate routes with different params:

       GET      /backoffice/users/:user_id/events(.:format)               backoffice/events#index
       DELETE   /backoffice/users/:id/close_account(.:format)             backoffice/users#close_account

in one route, the param is user_id and the route below is id. I wanted both to be user_id, so I added resources :users, param: :user_id

and now the routes are weirder than before:

      GET      /backoffice/users/:user_user_id/events(.:format)          backoffice/events#index
      DELETE   /backoffice/users/:user_id/close_account(.:format)        backoffice/users#close_account

how can I fix this routes in such a way that both routes have the same param?

Upvotes: 1

Views: 307

Answers (2)

Nick Roz
Nick Roz

Reputation: 4250

That is absolutely confusing, I agree. The simplest possible solution which utilizes Rails instrumentation is to use resources twice, one without specified param name and the other with it:

resources :users, only: [] do
  resources :events
end
resources :users, param: :user_id

In general one would use

resources :users, param: :number do
  resources :events
end
resources :users, param: :user_number

This will produce

GET    /users/:user_number/events(.:format)          /events#index
POST   /users/:user_number/events(.:format)          /events#create
GET    /users/:user_number/events/new(.:format)      /events#new
GET    /users/:user_number/events/:id/edit(.:format) /events#edit
GET    /users/:user_number/events/:id(.:format)      /events#show
PATCH  /users/:user_number/events/:id(.:format)      /events#update
PUT    /users/:user_number/events/:id(.:format)      /events#update
DELETE /users/:user_number/events/:id(.:format)      /events#destroy
GET    /users/new(.:format)                          /users#new
GET    /users/:user_number/edit(.:format)            /users#edit
GET    /users/:user_number(.:format)                 /users#show
PATCH  /users/:user_number(.:format)                 /users#update
PUT    /users/:user_number(.:format)                 /users#update
DELETE /users/:user_number(.:format)                 /users#destroy

If you prefer wrapping controllers in the module use scope instead.

Upvotes: 0

vijoc
vijoc

Reputation: 693

The parameters are not "wrong". The reason you're seeing this behavior is that the id parameter name is here reserved to the innermost resource. That is, if your EventsController had some other actions besides index, it would receive the event id as id, while the related User id would be user_id. The other route is not a nested resource, and as such has no need for different prefixes.

This can be seen in the Rails guides section on nested resources.

That being said, if you truly want both to be referred to as user_id, you should use

delete "/backoffice/users/:user_id/close_account/", to: "backoffice/users#close_account"

Upvotes: 2

Related Questions