【rails】namespace、scope、moduleでURLとディレクトリを変更する

※本サイトで紹介している商品・サービス等の外部リンクには、アフィリエイト広告が含まれる場合があります。

namespace

大規模なプロジェクトだと、コントローラーが数百できることがある

そのときコントローラーをフォルダでわけたら見やすくなる

namespaceとは、URLもコントローラーのディレクトリも変更する

namespace :admins do
  resources :articles
end

admins・・・複数形を使うのが基本

URLController
/admins/articles/:idadmins/articles#show
/admins/articlesadmins/articles#index

namespaceを使ってみる

commentslikeAPIを使っているので、わけてみる

routes.rbにて書き換える

  namespace :api do
    resources :comments, only: [:index, :new, :create]
    resource :like, only: [:show, :create, :destroy]
  end

↓ URLとコントローラーが変更されている


レスポンスを指定する

api_comments_path(GET)/api/comments(.:format)のformat部分を指定する

→ 「.html」「.json」のどちらでレスポンスを返すのかルール付けられる

  • http://localhost:3000/api/comments.html
    → htmlでレスポンスを返す
  • http://localhost:3000/api/comments.json
    → jsonでレスポンスを返す

api配下なのですべてjsonで返したい

routes.rbに書き加える

  namespace :api, defaults: {format: :json} do
    resources :comments, only: [:index, :create]
    resource :like, only: [:show, :create, :destroy]
  end

↓ {:format=>:json}が追加されている

URLの先頭にapiがつき、article_idがなくなってしまっている

このままでは記事の特定や取得ができない(コントローラーはこのままで問題ない)

今度はURLだけ変えてみる(scopeに続く)


scope

scopeはURLのみ変更する

scope :admins do
  resources :articles
end

URLController
/admins/articles/:idarticles#show
/admins/articlesarticles#index

scopeを使ってURLを変更してみる

先ほどarticle_idがなくなってしまったので、URLのみ変更する

  namespace :api, defaults: {format: :json} do
    scope '/articles/:article_id' do
      resources :comments, only: [:index, :create]
      resource :like, only: [:show, :create, :destroy]
    end
  end

↓ コントローラーは変わらず、URLだけ変更された

article_idが追加されたので、記事の特定・取得が可能になった)


「handle_heart.js」「article.js」のファイルでURLを修正する

`/articles/` → `/api/articles/`


コントローラーのディレクトリを変更する

先ほど変更したコントローラーについて、

apiディレクトリの中のcomments(likes)コントローラーになるように直す

  1. controllers/apiのフォルダ(ディレクトリ)を作る
  2. その中にまず、/application_controller.rbを作る
class Api::ApplicationController < ApplicationController
end

Apiに関わるメソッドで、配下のファイルにも一括で継承させたいときはこちらに書いておく

このときの「Api」の部分もnamecpaceという(先ほどのnamespaceとは違う意味らしい)

ディレクトリ名がapiなので、Api::と書いていくこと

comments(likes)_controller.rbをともに

apiの中に引っ張って移動させちゃう


新しいディレクトリ内ファイルの継承元について

  • どちらも、Api::のCommentsController(LikesController)と書く
  • 継承元もApi::ApplicationControllerと書く
class Api::CommentsController < Api::ApplicationController
class Api::LikesController < Api::ApplicationController
  1. Apiディレクトリ内のすべてのファイルに適用させたい、特有のメソッドがあるとき
  2. controllers/api/application_controller.rbに書く
  3. それを継承させたいので、CommentsController(LikesController)ともに
  4. 継承元はApi::ApplicationControllerになる

module

moduleはコントローラーのみ変更する

scope module :admins do
  resources :articles
end

URLを変更するとユーザーに見えてしまう → コントローラーだけ変更したら見えない

URLController
/articles/:idadmins/articles#show
/articlesadmins/articles#index

moduleを使ってみる

ログインしないと使えないアクションは「before_action :authenticate_user!」を忘れると厄介である

  • ログインしていないのに個人情報が見えちゃう
  • バグ発生の原因になる など

その対策として、ログインしないと使えないcontrollerをまとめた「apps」というディレクトリを作る

  1. controllers/appsのフォルダ(ディレクトリ)を作る
  2. その中にまず、/application_controller.rbを作る

before_action :authenticate_user!を書く

class Apps::ApplicationController < ApplicationController
  before_action :authenticate_user!
end

routes.rbで書き換える

  scope module: :apps do
    resources :favorites, only: [:index]
    resource :profile, only: [:show, :edit, :update]
    resource :timeline, only: [:show]
  end

あわせて、viewでもフォルダを作成する

appsの中に引っ張って移動させちゃう

URLはユーザーから見える部分

  • 「apps」が出てきたりなくなっていたりするのはキレイじゃない
  • ユーザーに関係のないものは見えなくてもいいんじゃないか

ということで、namespaceではなくmoduleでコントローラーのみ変更してみた

#DAY12