In my app I have a user model, school model, course model, and a syllabus model. A user or school could create courses which I have set through a polymorphic association (course belongs_to :hostable, and school/user has_many :courses, as: :hostable) , and a course has_one syllabus. My question is how to configure the routes for the nested course model which also has a syllabus model nested within it.
resources :users do
resources :courses do
resources :syllabus
end
member do
put :enroll
end
end
resources :schools do
resources :courses do
resources :syllabuses
end
member do
put :apply, :enroll
end
end
So users can enroll in courses by clicking a button on the course page, in my courses controller I have:
def enroll
@course = Course.find(params[:id])
current_user.coursegroups.create(host_course_id: @course.id, role: 'applicant')
respond_with @course
end
So, is this the correct way to configure my routes?
Stefan’s right that you should be careful about nesting resources more than one level deep, but I personally don’t find nesting unmanageable until two levels. Either way, it’s just a personal preference.
For your routes, the one thing that immediately jumps out at me is that nesting everything inside users and schools isn’t necessary, since it sounds like you’ll be logging in as a user or school. Routes with the logged-in user in them are very difficult to manage: users can’t share them and they don’t really reflect the state of the specified resource. For example:
Theoretically,
courses/14/syllabus/3should work the same for every logged-in user, but anyone trying to share a link to this would need to include their own user ID number first, which is somewhat silly. Instead structure your routes like so:In your session, allow either a user or school to log in, and vary what they see in the views (and what resources they’re allowed to access) based on who’s logged in using something like CanCan. Now your routes will reflect the actual resource (
/courses/14/syllabus/3) correctly.