Rails 3 Levels of Nested Resources

I know that many rail developers say that nesting your resources over two levels is an offense. I also agree because it gets messy when your urls look like mysite.com/account/1/people/1/notes/1. I am trying to find a way to use nested resources, but not nested in 3 levels.

This is the wrong way to do this, as rails developers do not recommend it, and it is also very difficult to figure out how to embed this in a controller or form view.

resources :account do resources :people do resources :notes end end 

The right rails developer says this should be done like this:

 resources :account do resources :people end resources :people do resources :notes end 

Here is the problem that I always run into. When I visit the account / 1 / person, I can add the person to the account and say that the URL is like mysite.com/account/1/people/1 and that works fine.

Now, if I try to access mysite.com/people/1/notes from account 1, I get an error

Unable to find people without account ID

How to make this work correctly?

+8
source share
2 answers

You insert routes as deep as you like, since 3.x rails let you smooth them using shallow: true

Try experimenting with

 resources :account, shallow: true do resources :people do resources :notes end end 

Use rake routes to find out what you get :)

UPDATE in response to comment

As I said, play with rake routes to find out which url you can get

 resources :account, shallow: true do resources :people, shallow: true do resources :notes end end 

gets these routes

 :~/Development/rails/routing_test$ rake routes person_notes GET /people/:person_id/notes(.:format) notes#index POST /people/:person_id/notes(.:format) notes#create new_person_note GET /people/:person_id/notes/new(.:format) notes#new edit_note GET /notes/:id/edit(.:format) notes#edit note GET /notes/:id(.:format) notes#show PUT /notes/:id(.:format) notes#update DELETE /notes/:id(.:format) notes#destroy account_people GET /account/:account_id/people(.:format) people#index POST /account/:account_id/people(.:format) people#create new_account_person GET /account/:account_id/people/new(.:format) people#new edit_person GET /people/:id/edit(.:format) people#edit person GET /people/:id(.:format) people#show PUT /people/:id(.:format) people#update DELETE /people/:id(.:format) people#destroy account_index GET /account(.:format) account#index POST /account(.:format) account#create new_account GET /account/new(.:format) account#new edit_account GET /account/:id/edit(.:format) account#edit account GET /account/:id(.:format) account#show PUT /account/:id(.:format) account#update DELETE /account/:id(.:format) account#destroy 

As you can see, you have access to all models at any level that you need. The rest depends on what you have invested in the actions of your controller.

You really need to work on actions to make sure that you perform the appropriate actions when id parameters are not passed, so if you are using an identifier for a specific model, check that the identifier is in the parameter list and if you do not take alternative actions. for example, if you do not pass the account ID, then make sure that you are not trying to use it.

Your comment says that you already use shallow routes, but is that not what you posted in your question?

+11
source

it works for me. many thanks

0
source

All Articles