2012-07-26 125 views
0

我有4个模型。 Departments,Courses,SectionsTeacher 所有这些都与正确的belongs_tohas_many关系妥当。一节属于属于一个部门的课程。老师有很多部分,然而,一门课程有很多(由许多不同的老师教授)。在Rails中创建自定义网址

我想构建网站以这样的方式使URL /view/department_name/course_name/section_name/显示名称为section_name,属于一个名为couse_name的过程中,属于部门department_name部分。

但是,我也想要/view/teacher_name/course_name/section_name以相同的方式工作,它显示了与该教师相关的所有部分。

我该怎么做?

供参考:不同的模型通过它们在数据库中的ID进行连接。部分有一个与它关联的course_id整数,而course有一个department_id整数。部门也有一个department_id,这是多余的,但这就是我设置它的方式。

我的routes.rb

Test2::Application.routes.draw do 
    resources :courses 
    resources :departments 
    resources :teachers 
    resources :sections 
    resources :courses 
+0

你应该发布您的routes.rb文件来更好地描述问题 – 2012-07-26 04:03:40

+0

好吧,我用它更新了OP。 – Bass 2012-07-26 04:19:36

+1

http://railscasts.com/episodes/139-nested-resources 看这个,也许它会帮助 – 2012-07-26 04:22:43

回答

1

你提到的东西就像在你的路线section_name。你应该确保这些名称都是URL安全的。

另一点你必须考虑的是你想要的两条路径其实非常相似,因此你可能需要在同一个控制器动作中处理这两个路径。

/view/department_name/course_name/section_name 
/view/teacher_name/course_name/section_name 

唯一不同的部分是department_name vs teacher_name。但愿没有任何老师有相同的名称与您所在的部门XD”

,你可以定义路径:

get '/view/:department_or_teacher_name/:course_name/:section_name' => 'some_controller#some_action' 
在你的行动

然后,你需要的东西是这样的:

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 

以上生成3个查询,可能不太好,您可以考虑使用连接:

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 

猜测部门或老师仍然有困难。所以,如果你重新定义这样的路径,上面可能会更清洁:

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 

这是主意。我没有测试它,只是猜测。所以请告诉我你是否遇到任何问题。