Steve
Steve

Reputation: 4566

Does every belongs_to has_many association need nested routes?

This is a fairly basic question but I haven't been able to find concrete answers online. Every has_many belongs_to does not need nested routes correct? Should you only use nested routes when you're looking for URLs of the form class/:id/class/:id?

For example, let's say I have two classes Profile and Post.

models/profile

has_many :posts

models/post

belongs_to :profile

There's no separate post URL, the posts are displayed in profiles/show. Should the post routes (in this case it would be only actions like :new, :create, and :destroy) be nested inside the :profiles resource? The rails guide states that resources should not be nested more than one level deep and there are often times. Making nested resources for every association seems like it would violate this rule very quickly. Thanks in advance!

Upvotes: 1

Views: 2796

Answers (2)

Deej
Deej

Reputation: 5352

If you read Section 2.7 of the Ruby on Rails Guide it states that:

Nested routes allow you to capture this relationship in your routing.

See - http://guides.rubyonrails.org/routing.html#resource-routing-the-rails-default for reference.

Further to this you may want to perform particular operations on a class i.e. user which has create, edit etc ... every user is associated with a particular booking. That means that whenever you do anything to a user, you really are doing something to an user/booking. Because this is associated with this.

RESTful routes is a clean way of setting your application and making good use of unified resource identifiers. An example of this would be identifying a particular user such as /users/1/bookings/3 this would show the first user.

Upvotes: 1

Sascha Kaestle
Sascha Kaestle

Reputation: 1293

If you have no use for /profile/1/posts or /profile/1/posts/1 you do not need the nested routes. However, I urge you to rethink, nested routes make for clean RESTful APIs

For example, the neat little nested route:

resources :profile, :shallow => true do
  resources :posts
end

will give you all these realy useful routes:

   profile_posts GET    /profile/:profile_id/posts(.:format)     posts#index
                 POST   /profile/:profile_id/posts(.:format)     posts#create
new_profile_post GET    /profile/:profile_id/posts/new(.:format) posts#new
       edit_post GET    /posts/:id/edit(.:format)                posts#edit
            post GET    /posts/:id(.:format)                     posts#show
                 PUT    /posts/:id(.:format)                     posts#update
                 DELETE /posts/:id(.:format)                     posts#destroy
   profile_index GET    /profile(.:format)                       profile#index
                 POST   /profile(.:format)                       profile#create
     new_profile GET    /profile/new(.:format)                   profile#new
    edit_profile GET    /profile/:id/edit(.:format)              profile#edit
         profile GET    /profile/:id(.:format)                   profile#show
                 PUT    /profile/:id(.:format)                   profile#update
                 DELETE /profile/:id(.:format)                   profile#destroy

This way you have to freedom to choose the nested route when necessary/useful, such as

GET /profile/:profile_id/posts/new(.:format) # create a new post for the given profile_id
GET /profile/:profile_id/posts(.:format) # return all posts for the given profile_id

and use the shallow routes where the nested routes are not necessary

Upvotes: 3

Related Questions