0

私は4つのモデルを持っています。Departments、、、および それらのすべては、適切な関係と階層的に接続されてCoursesいます。セクションは、部門に属するコースに属します。教師には多くのセクションがありますが、コースには多くの(多くの異なる教師によって教えられている)教師がいます。SectionsTeacherbelongs_tohas_many

URLに、部門に属する、という名前のコースに属する/view/department_name/course_name/section_name/、という名前のセクションが表示されるようにサイトを構築したいと思います 。section_namecouse_namedepartment_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
4

1 に答える 1

1

section_nameあなたはあなたのルートのようなことについて言及しました。名前がすべてURLセーフであることを確認する必要があります。

考慮しなければならないもう1つのポイントは、必要な2つのパスが実際には非常に類似しているため、同じコントローラーアクションで両方を処理する必要がある場合があることです。

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

唯一の異なる部分は、department_nameと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

これがアイデアです。私はそれをテストしませんでした、そしてただ推測によって。問題が発生した場合は教えてください。

于 2012-07-26T05:18:21.457 に答える