Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: nesting same resource in multiple nested restful routes?

This is pretty easy but switching back n' forth between frameworks/languages has me doubting myself. Trying to work out routes for has_many :through relationship in Rails.

#User
has_many :reservations, :dependent => :destroy
has_many :events, :through => :reservations

#Reservation
belongs_to :user
belongs_to :event

#Event
has_many :reservations, :dependent => :destroy
has_many :attendees, through => :reservations, :source => :user

I want routes where from a User model I can quickly build/create a new reservation to a specific Event (& vice versa) but not sure how to go about creating them. This looks odd:

resources :users do
  resources :reservations, only: [:new, :create, :destroy]
end

resources :events do
  resources :reservations, only: [:new, :create, :destroy]
end

Anyway, just looking for verification, or perhaps an alternative way to handle this. Ideally there's a link on a page next to event that a user could click and (either through ajax or page reload) they would have made a 'reservation'.

By the same token I need route to see every user who has a reservation to an given event. And every event that a given user is reserved for.

like image 854
Meltemi Avatar asked Feb 18 '23 20:02

Meltemi


2 Answers

Good question! I think I would go with this set of routes:

resources :events do
  resources :reservations, only: [:new, :create, :destroy]
end

resources :users do
  get 'reservations', :on => :member
end

Your reservations will be closely tied with the events. I think this makes sense from a modeling standpoint. Based on your description, it sounds like a logged in user will click a link to create a reservation when under an event. By associating the reservations with the events, you know which event to build the reservation for simply from the route and because you have an authenticated user, you can assume which user to use as well (Probably from your session). For example, a route like POST to /events/5/reservations would create a reservation for the currently logged in user for event 5.

The additional get action on the user resource allows you to provide an endpoint to answer the question What reservations does a particular user have?

Ideally, you want to make sure you only have one set of endpoints for managing resources. In terms of fetching additional information through non-resource actions, that's more a matter of preference and what use cases you want to support.

like image 94
Marc Baumbach Avatar answered May 09 '23 09:05

Marc Baumbach


I would use this to DRY routes:

def reserv
  resources :reservations, only: [:new, :create, :destroy]
end

resources :users do
  reserv
end

resources :events do
  reserv
end
like image 25
Jonas Avatar answered May 09 '23 10:05

Jonas