1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

第10章|今さら学ぶ「ルーティングとRESTfulリソース」

1
Last updated at Posted at 2026-02-20

第10章|今さら学ぶ「ルーティングとRESTfulリソース」

📚 シリーズ目次はこちら → 「今さら学ぶ」シリーズ — はじめに
🗺️ KnowledgeNoteの設計を確認 → 設計マップ

この章でわかること

  • resources :articles が自動で生む7つのルートの全体像
  • RESTful設計とは何か — 「統一されたURLの作法」
  • only: / except: で必要なルートだけ開ける方法
  • 名前付きルート(_path / _url)の仕組み
  • ネストしたリソースと member / collection の使い方

🏠 たとえ話で掴む「ルーティング」

ルーティングは、第0章で「コールセンター」、第6章で「図書館の窓口」にたとえました。今回はもう少し具体的に、 市役所の窓口 で整理します。

市役所に行くと、「住民票の窓口」「戸籍の窓口」「税金の窓口」と目的別に窓口が分かれています。そして各窓口では「発行してほしい(GET)」「届出を出したい(POST)」「変更したい(PATCH)」「取り消したい(DELETE)」といった手続きができます。

Railsの resources は、 1つのリソース(たとえば記事)に対して、必要な窓口を7つまとめて自動で開設する仕組み です。

resources :articles
# ↓ これだけで7つの窓口(ルート)が開く
窓口番号 HTTPメソッド URL アクション 市役所のたとえ
GET /articles index 記事の一覧を見せてください
GET /articles/new new 新しい記事の申請書をください
POST /articles create 申請書を提出します(新規作成)
GET /articles/:id show 1番の記事を見せてください
GET /articles/:id/edit edit 1番の記事の変更届をください
PATCH /articles/:id update 変更届を提出します(更新)
DELETE /articles/:id destroy 1番の記事を取り消してください

たった1行の resources :articles で、これだけの窓口が自動で用意されます。これがRailsの規約の力です。


ルーティングとは何か — 技術的な定義

URLとコントローラを結びつける仕組み

ルーティング(Routing) は、HTTPリクエスト(URLとHTTPメソッドの組み合わせ)を受け取り、それを どのコントローラのどのアクションで処理するか を決定するマッピング機構です。

Webアプリに届くリクエストは、すべて「URL + HTTPメソッド」の組み合わせで表現されます。GET /articles/1 というリクエストが来たとき、Railsのルーターは config/routes.rb の定義を参照して ArticlesController#show を呼び出す、という対応付けを行います。

RESTとは

REST(Representational State Transfer) は、2000年にRoy Fieldingが提唱したWebの設計思想です。RESTでは、Web上のすべてのものを「リソース」として扱い、URLでリソースを特定し、HTTPメソッドで操作の種類を表現します。

Railsの resources メソッドは、このREST設計をRubyのDSL(ドメイン固有言語)として簡潔に表現したものです。1行書くだけで7つのルートが生成される仕組みは、RESTの規約をRailsのCoCに落とし込んだ設計です。


🌐 RESTful設計とは

RESTの基本的な考え方

RESTが提唱する内容は、難しく聞こえますがポイントは1つだけです。

「URLはリソース(もの)を表し、HTTPメソッドで操作を表す」

✅ RESTfulなURL設計
  GET    /articles       → 記事の一覧を取得
  POST   /articles       → 記事を新規作成
  GET    /articles/1     → 記事1件を取得
  PATCH  /articles/1     → 記事を更新
  DELETE /articles/1     → 記事を削除

❌ RESTfulでないURL設計
  GET /getArticleList         → URLに動詞が入っている
  POST /createNewArticle      → 動詞がURL側にある
  GET /articles/delete/1      → DELETEなのにGETを使っている

RESTfulな設計では、 URLは「何を」を表し、HTTPメソッドは「どうする」を表す と役割を分けます。この統一ルールに従うことで、URLを見ただけで「何をしているか」がわかります。

なぜRESTfulが大事か

■ 開発者にとって
  → URLの設計で迷わない。「記事の操作なら /articles」と統一
  → チームメンバーがURLを見ただけで処理を推測できる

■ 面接で
  → 「RESTful設計」は頻出質問。resources の7アクションを説明できることが大事

🔧 only: / except: — 必要な窓口だけ開ける

resources は7つのルートを一気に作りますが、全部必要とは限りません。KnowledgeNoteのコメント機能では「作成」と「削除」だけあればいい、という場合もあります。

# 7つ全部開ける
resources :articles

# 必要なものだけ指定(allowlist方式)
resources :comments, only: [:create, :destroy]
# → create と destroy の2つだけ

# 不要なものを除外(denylist方式)
resources :users, except: [:new, :create]
# → new と create 以外の5つ

# onlyの方がよく使われる(何が開いているか明確だから)

市役所にたとえると、「コメント窓口は、提出と取り消しだけ受け付けます。閲覧窓口はありません」ということです。 不要な窓口を開けっぱなしにしない のは、セキュリティの観点でも大切です(→ 第20章で詳しく扱います)。


🏷️ 名前付きルート — URLのニックネーム

resources で生成されるルートには、 名前(ニックネーム) がつきます。URLを直接書く代わりに、この名前を使ってリンクを生成できます。

resources :articles
ヘルパー名 生成されるURL 使い方
articles_path /articles 一覧ページへのリンク
new_article_path /articles/new 新規作成ページへのリンク
article_path(article) /articles/1 記事詳細ページへのリンク
edit_article_path(article) /articles/1/edit 編集ページへのリンク

_path と _url の違い

article_path(article)   # => "/articles/1"(相対パス)
article_url(article)    # => "http://localhost:3000/articles/1"(絶対URL)
ヘルパー 返すもの 使いどころ
_path /articles/1 ビュー内のリンク(ほとんどこちら)
_url http://... メール本文内のリンクなど、ドメイン名まで必要な場面

普段は _path を使えば十分 です。_url が必要なのは、メール本文にリンクを入れるときなど、ドメイン名まで含む完全なURLが必要な場面です。

なぜ名前付きルートを使うのか

<!-- ❌ URLを直接書く — URLが変わったら全部修正が必要 -->
<a href="/articles/<%= article.id %>">記事を見る</a>

<!-- ✅ 名前付きルートを使う — URLが変わっても1箇所の修正で済む -->
<%= link_to "記事を見る", article_path(article) %>

URL構造を変更しても、ルーティングを1箇所直すだけで、ビュー側の修正が不要になります。これもDRY原則の実践です。


🔀 ネストしたリソース — 部署の中の担当者

KnowledgeNoteでは、コメントは必ず記事に紐づきます。「どの記事のコメントか」をURLで表現するのが ネストしたリソース です。

# config/routes.rb
resources :articles do
  resources :comments, only: [:create, :destroy]
end

これにより、以下のルートが生成されます。

HTTPメソッド URL アクション
POST /articles/:article_id/comments comments#create
DELETE /articles/:article_id/comments/:id comments#destroy

URLを見るだけで「記事3のコメントを作成する」「記事3のコメント5を削除する」という意味がわかります。

# app/controllers/comments_controller.rb
class CommentsController < ApplicationController
  def create
    @article = Article.find(params[:article_id])   # URLから記事を特定
    @comment = @article.comments.build(comment_params)
    @comment.user = current_user

    if @comment.save
      redirect_to @article, notice: "コメントを投稿しました"
    else
      redirect_to @article, alert: "コメントの投稿に失敗しました"
    end
  end

  def destroy
    @article = Article.find(params[:article_id])
    @comment = @article.comments.find(params[:id])
    @comment.destroy
    redirect_to @article, notice: "コメントを削除しました"
  end

  private

  def comment_params
    params.expect(comment: [:body, :parent_id])  # Rails 8.0の書き方(→ [第13章](https://qiita.com/harapeco-mgn/items/15d2edb98bde321b3b10)で詳しく解説)
  end
end

ネストの深さに注意

# ❌ ネストが深すぎる — URLが長くなりすぎて使いにくい
resources :users do
  resources :articles do
    resources :comments do
      resources :likes        # /users/1/articles/2/comments/3/likes/4 😱
    end
  end
end

# ✅ ネストは1段階まで — Railsの慣習
resources :articles do
  resources :comments, only: [:create, :destroy]   # 1段階のネスト
end
resources :likes, only: [:create, :destroy]         # いいねはネストしない

一般的に、 ネストは1段階まで にするのがRailsの慣習です。深くなりすぎるとURLが長くなり、コントローラも複雑になります。


🎯 member と collection — 特別な窓口を追加する

7つの標準アクション以外に、追加のルートが必要な場合があります。KnowledgeNoteでは、ユーザーの「フォロー中一覧」「フォロワー一覧」がそれにあたります。

member — 特定の1件に対する追加アクション

resources :users, only: [:index, :show, :edit, :update, :destroy] do
  member do
    get :following    # GET /users/:id/following
    get :followers    # GET /users/:id/followers
  end
end

member特定のユーザー(:id指定) に対するアクションを追加します。「ユーザー3のフォロー一覧」のように、IDが必要です。

collection — コレクション全体に対する追加アクション

resources :articles do
  collection do
    get :search       # GET /articles/search
  end
end

collection記事全体 に対するアクションを追加します。特定のIDは不要です。「記事を検索する」のように、コレクション全体を対象にした操作に使います。

member と collection の違い

member collection
URL /users/:id/following /articles/search
:id 必要(特定の1件) 不要(全体が対象)
使い方 following_user_path(user) search_articles_path

🔍 ルーティングの確認方法

定義したルートを確認するコマンドがあります。開発中によく使います。

# 全ルートを一覧表示
$ rails routes

# 特定のコントローラのルートだけ表示
$ rails routes -c articles

# grepで絞り込み
$ rails routes | grep article
# 出力例
      Prefix Verb   URI Pattern                  Controller#Action
    articles GET    /articles(.:format)           articles#index
             POST   /articles(.:format)           articles#create
 new_article GET    /articles/new(.:format)       articles#new
edit_article GET    /articles/:id/edit(.:format)  articles#edit
     article GET    /articles/:id(.:format)       articles#show
             PATCH  /articles/:id(.:format)       articles#update
             PUT    /articles/:id(.:format)       articles#update
             DELETE /articles/:id(.:format)       articles#destroy

Prefix の列が名前付きルートのヘルパー名(_path / _url をつけて使う)です。


🛠️ KnowledgeNoteでの具体例

KnowledgeNoteの routes.rb 全体を確認します。ここまで学んだ概念がすべて使われています。

# config/routes.rb
Rails.application.routes.draw do
  # トップページ
  root "static_pages#home"

  # カスタムルート(名前付き)
  get    "/about",  to: "static_pages#about"
  get    "/signup", to: "users#new"
  post   "/signup", to: "users#create"
  get    "/login",  to: "sessions#new"
  post   "/login",  to: "sessions#create"
  delete "/logout", to: "sessions#destroy"

  # ユーザー(member でフォロー一覧を追加)
  resources :users, only: [:index, :show, :edit, :update, :destroy] do
    member do
      get :following, :followers
    end
  end

  # 記事(ネストしたコメント付き)
  resources :articles do
    resources :comments, only: [:create, :destroy]
  end

  # フォロー・いいね(作成と削除のみ)
  resources :follows,       only: [:create, :destroy]
  resources :likes,         only: [:create, :destroy]

  # タグ(名前で検索)
  resources :tags,          only: [:show], param: :name

  # 通知(一覧のみ)
  resources :notifications, only: [:index]

  # メール認証・パスワード再設定
  resources :account_activations, only: [:edit]
  resources :password_resets,     only: [:new, :create, :edit, :update]
end

注目ポイントをいくつか取り上げます。

# ① カスタムURL — /signup は users#new より直感的
get "/signup", to: "users#new"    # /users/new でもアクセスできるが、
                                  # /signup の方がユーザーにわかりやすい

# ② param: :name — IDではなくタグ名でアクセス
resources :tags, only: [:show], param: :name
# → GET /tags/Ruby(IDではなく名前でアクセス)

# ③ only: で必要なルートだけ開ける
resources :likes, only: [:create, :destroy]
# → いいねは「つける」と「外す」だけ。一覧や編集は不要

💼 面接で聞かれたら?

Q:RESTful設計について説明してください。

「RESTfulとは、URLでリソース(対象)を表し、HTTPメソッドで操作を表す設計指針です。たとえば /articles というURLに対して、GETで取得、POSTで作成、PATCHで更新、DELETEで削除を行います。Railsでは resources メソッドで、1つのリソースに対するCRUD操作のルートを7つ自動生成できます。」

深掘りされたら:

  • 「7つのアクションを全部言えますか?」→ index(一覧)、show(詳細)、new(作成フォーム)、create(作成処理)、edit(編集フォーム)、update(更新処理)、destroy(削除)。
  • 「ネストしたリソースとは?」→ コメントのように、親リソース(記事)に従属する子リソースをURLで表現する仕組み。/articles/:article_id/comments のように、親のIDをURLに含める。ネストは1段階までが慣習。

🔗 もっと深く知りたい人へ(1次情報リンク)


まとめ

  • resources :articles で7つのRESTfulルートが自動生成される
  • ✅ RESTfulとは「URLはリソース、HTTPメソッドは操作」を表す統一設計
  • only: で必要なルートだけ開ける。不要な窓口は閉じておく
  • ✅ 名前付きルート(_path / _url)でURLをニックネームで管理し、DRYを実現
  • ✅ ネストしたリソースは1段階まで。member は個別、collection は全体への追加アクション

📚 シリーズ目次:「今さら学ぶ」シリーズ — はじめに

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?