在Rails中创建自定义URL

时间:2012-07-26 03:24:44

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.2

我有4个型号。 DepartmentsCoursesSectionsTeacher 所有这些都与正确的belongs_tohas_many关系保持联系。部分属于属于部门的课程。教师有很多部分,但是,一门课程有许多(由许多不同的教师教授)。

我想以URL的方式构建网站 /view/department_name/course_name/section_name/显示名称为section_name的部分,该部分属于名为couse_name的课程,属于部门department_name

但是,我还希望/view/teacher_name/course_name/section_name以相同的方式工作,它会显示与该教师相关的所有部分。

我该怎么做?

仅供参考:不同的模型通过数据库中的ID进行连接。 Section有一个与之关联的course_id整数,并且当然有一个department_id整数。该部分还有一个department_id,这是多余的,但这就是我设置它的方式。

my routes.rb

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

1 个答案:

答案 0 :(得分: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

这是个主意。我没有测试它,只是猜测。如果您遇到任何问题,请告诉我。