今回はルーティングにおけるnamespaceとscope、moduleの3つの違いと使い方について簡単にまとめたので紹介したいと思います。namespace/scope/moduleを組み合わせることで大抵のURLを設計できるため、ルーティングを書く際の参考にしてください。
まず始めに
rails routes
を実行することで表示される項目として「Prefix」「Verb」「URI Pattern」「Controller#Action」があります。今回はこれらを操作していきます。
URL設計
今回のURL設計ではschool(学校)とclassroom(クラス)とstudent(生徒)の3つを題材として扱います。最初のルーティングとしてはstudents(生徒)に関するアクションのみ(resources :students
のみ)記述されているとします。
Rails.application.routes.draw do
resources :students
end
namespace
namespaceは「URI Pattern」と「Controller#Action」の2つを同時にカスタマイズしたい場合に使用します。
例えば「URI Pattern」を/classroom/students
に「Controller#Action」をclassroom/students#〇〇
にしたい場合は以下のように記述します。
Rails.application.routes.draw do
namespace :classroom do
resources :students
end
end
ファイル構成としてはclassroom配下のstudentsコントローラになります。
# app/controllers/classroom/students_controller.rb
module Classroom
class StudentsController < ApplicationController
def index
@students = Student.all
end
end
end
また「URI Pattern」をschool/classrooms/students
に「Controller#Action」をschool/classrooms/students#〇〇
にしたい場合は、以下のようにnamespaceをネストすることで実現できます。ファイル構成としては、school/classrooms配下のstudentsコントローラになります。
Rails.application.routes.draw do
namespace :school do
namespace :classrooms do
resources :students
end
end
end
# app/controllers/school/classrooms/students_controller.rb
module School
module Classrooms
class StudentsController < ApplicationController
def index
@students = Student.all
end
end
end
end
scope
scopeは「URI Pattern」のみカスタマイズしたい場合に使用します。
例えば「URI Pattern」のみ/classroom/students
に変更したい場合は以下のように記述します。
Rails.application.routes.draw do
scope :classroom do
resources :students
end
end
「Controller#Action」の変更は行われていないため、ファイル構成としてはstudentsコントローラになります。
# app/controllers/students_controller.rb
class StudentsController < ApplicationController
def index
@students = Student.all
end
end
また「URI Pattern」のみをschool/classrooms/students
にしたい場合は、scopeをネストすることで実現できます。ファイル構成は変わらずstudentsコントローラになります。
Rails.application.routes.draw do
scope :school do
scope :classrooms do
resources :students
end
end
end
# app/controllers/students_controller.rb
class StudentsController < ApplicationController
def index
@students = Student.all
end
end
module(scope module)
module(scope module)は「Controller#Action」のみカスタマイズしたい場合に使用します。
例えば「Controller#Action」のみclassroom/students#〇〇
に変更したい場合は以下のように記述します。
Rails.application.routes.draw do
scope module: :classroom do
resources :students
end
end
ファイル構成としてはclassroom配下のstudentsコントローラになります。
# app/controllers/classroom/students_controller.rb
module Classroom
class StudentsController < ApplicationController
def index
@students = Student.all
end
end
end
また「Controller#Action」のみschool/classrooms/students#〇〇
に変更したい場合は以下のようにmodule(scope module)をネストさせます。
Rails.application.routes.draw do
scope module: :school do
scope module: :classrooms do
resources :students
end
end
end
# app/controllers/school/classrooms/students_controller.rb
module School
module Classrooms
class StudentsController < ApplicationController
def index
@students = Student.all
end
end
end
end
ちなみに
ちなみにですが、school(学校)とclassroom(クラス)とstudent(生徒)の関係で、とある学校のとあるクラスの生徒一覧をURLに表したい場合は/schools/school_id/classrooms/classroom_id/students
のようになります。
まとめ
- namespaceは「URI Pattern」と「Controller#Action」の2つを同時にカスタマイズしたい場合に使用する
- scopeは「URI Pattern」のみカスタマイズしたい場合に使用する
- module(scope module)は「Controller#Action」のみカスタマイズしたい場合に使用する
参考
今回はルーティングにおけるnamespaceとscope、moduleの3つの違いと使い方について紹介しました。URL設計の際にごっちゃになってしまう部分のため、参考になれば幸いです。