しおブログ言うてますけど

技術ブログ言うてますけど技術以外のことも発信すると思われ。RubyとかRuby on Railsとか生き方とかジャンルにこだわらず自分の好きなように。初心者なのでお手柔らかに。

名前空間ってなに?って疑問を解消してみた

こんにちは。たかあきです。
現場Railsで勉強していると名前空間モジュールといった難しい(?)言葉が出てくる。
モジュールはクラスと違い、継承ができないといった特徴があるが、名前空間ってなんぞや...となったのでRailsのルーティングにおけるモジュールと名前空間についてまとめる。

モジュールについて

まずモジュールの使い方をまとめてみる。

module Animal
  def self.dog
    '犬です'
  end

  def cat
    '猫です'
  end
  module_function :cat
end

puts Animal.dog #=>犬です
puts Animal.cat #=>猫です

モジュールからメソッドを呼び出すときは上記のように呼び出す。

名前空間について

名前空間名前の衝突を避けるために使う概念である。
どういうことか。
プログラムが複雑になると他の人が作成したクラス名やメソッド名と重複してしまう可能性が出てくる。
しかしモジュールを名前空間として使用することで重複を避けることができる。

class Animal
  def dog
    '犬です'
  end
end

# モジュールZooを名前空間としてAnimalクラスを定義
module Zoo
  class Animal
    def dog
      '動物園の犬です'
    end
  end
end

# Userクラスのインスタンスメソッドを実行
puts Animal.new.dog #=>犬です

# 名前空間を利用する場合、「モジュール名 + :: + クラス名」 とする
puts Zoo::Animal.new.dog #=> 動物園の犬です

このように名前空間を利用することで同じクラス名、メソッド名が使えるようになる。

ルーティングにおけるnamespaceとscopeの違い

namespace

namespaceは、URLもcontroller格納フォルダも、指定のパスになる

namespace :admin do
  resources :users
end

#rails routes

   admin_users GET    /admin/users(.:format)          admin/users#index
               POST   /admin/users(.:format)          admin/users#create
new_admin_user GET    /admin/users/new(.:format)      admin/users#new
dit_admin_user GET    /admin/users/:id/edit(.:format) admin/users#edit
    admin_user GET    /admin/users/:id(.:format)      admin/users#show
               PATCH  /admin/users/:id(.:format)      admin/users#update
               PUT    /admin/users/:id(.:format)      admin/users#update
               DELETE /admin/users/:id(.:format)      admin/users#destroy

namespaceはコントローラを名前空間によってグループ化することができる。 管理者用のコントローラはcontrollers/adminディレクトリ以下に作成して管理するみたいなことができる。

scope

scopeはcontrollerの格納フォルダだけ、指定パスになる。

scope module: :admin do
  resources :users
end

#rails rotues

   Prefix Verb   URI Pattern               Controller#Action
    users GET    /users(.:format)          admin/users#index
          POST   /users(.:format)          admin/users#create
 new_user GET    /users/new(.:format)      admin/users#new
edit_user GET    /users/:id/edit(.:format) admin/users#edit
     user GET    /users/:id(.:format)      admin/users#show
          PATCH  /users/:id(.:format)      admin/users#update
          PUT    /users/:id(.:format)      admin/users#update
          DELETE /users/:id(.:format)      admin/users#destroy

URLは変更したくないがコントローラーはグループ化したいという場合はこのようにする。

scopeのみ

また、scope '/admin'のようにすると上記の逆で、URLだけ、指定のパスになる。

scope '/admin' do
  resources :tweets
end

#rails rotues

   Prefix Verb   URI Pattern                     Controller#Action
    users GET    /admin/users(.:format)          users#index
          POST   /admin/users(.:format)          users#create
 new_user GET    /admin/users/new(.:format)      users#new
edit_user GET    /admin/users/:id/edit(.:format) users#edit
     user GET    /admin/users/:id(.:format)      users#show
          PATCH  /admin/users/:id(.:format)      users#update
          PUT    /admin/users/:id(.:format)      users#update
          DELETE /admin/users/:id(.:format)      users#destroy

まとめ

  • 名前空間は名前の衝突を避けるために使う概念。
  • ルーティングにおけるnamespaceはURLもcontroller格納フォルダも、指定のパスになることで、管理者用のURLとコントローラーを作成することができる。

ルーティングの設定とか調べたらまだまだたくさんあったが、名前空間がどういうものなのかということは理解できた。