You mentioned things like section_name in your routes. You should make sure the names are all URL-safe.
Another point you have to consider is the two paths you want is in fact quite similar and thus you may need to handle both in the same controller action.
/view/department_name/course_name/section_name
/view/teacher_name/course_name/section_name
The only different part is the department_name vs teacher_name. Hopefully there is no any teacher have the same name with your department XD"
You may define the path as:
get '/view/:department_or_teacher_name/:course_name/:section_name' => 'some_controller#some_action'
Then in your action, you need something like this:
def some_action
department_or_teacher = Department.find_by_name(params[:department_or_teacher_name]) || Teacher.find_by_name(params[:department_or_teacher_name])
course = Course.find_by_name(params[:course_name])
q = Section.where(name: params[:section_name]).where(course_id: course.id)
if department_or_teacher.class.name == "Department"
q = q.where(department_id: q.id)
elsif department_or_teacher.class.name == "Teacher"
q = q.where(teacher_id: q.id)
end
@section = q.first # I assume there should be only 1 section with a given name, under a specific course, and (under a specific department or a specific teacher)
end
The above generates 3 queries, which might not be very good. You may consider using joins:
def some_action
department_or_teacher = Department.find_by_name(params[:department_or_teacher_name]) || Teacher.find_by_name(params[:department_or_teacher_name])
q = Section.where(name: params[:section_name]).joins(:course).where("courses.name = ?", params[:course_name])
if department_or_teacher.class.name == "Department"
q = q.where(department_id: q.id)
elsif department_or_teacher.class.name == "Teacher"
q = q.where(teacher_id: q.id)
end
@section = q.first
end
There is still a difficulty in guessing the department or teacher. So if you redefine the path to something like this, the above could be cleaner:
get '/view/department/:department_name/:course_name/:section_name' => 'some_controller#some_action_for_department'
get '/view/teacher/:teacher_name/:course_name/:section_name' => 'some_controller#some_action_for_teacher'
def some_action_for_department
@section = Section.where(name: params[:section_name])
.joins(:course).where("courses.name = ?", params[:course_name])
.joins(:department).where("departments.name = ?", params[:department_name]) # you mentioned there is a department_id in sections, thus you could actually setup a belongs_to :department in section
.first
end
def some_action_for_teacher
@section = Section.where(name: params[:section_name])
.joins(:course).where("courses.name = ?", params[:course_name])
.joins(:teacher).where("teachers.name = ?", params[:teacher_name])
.first
end
This is the idea. I did not test it and just by guess. So please tell me if you encountered any problems.