カテゴリ: Rails 更新日: 2026/02/17

RailsのPundit::Scopeで一覧を絞り込む方法を完全解説!ロール・所有者別の認可を初心者向けに理解しよう

Pundit::Scopeで一覧を絞り込む:ロール/所有者別のアクセス制御
Pundit::Scopeで一覧を絞り込む:ロール/所有者別のアクセス制御

先生と生徒の会話形式で理解しよう

生徒

「Railsでログインしている人ごとに、見られる一覧を変えたいんですが、どうすればいいですか?」

先生

「Railsでは、Punditという認可ライブラリを使うと、安全に一覧データを絞り込めます。」

生徒

「一覧って、全部表示しちゃダメなんですか?」

先生

「ダメな場合が多いですね。Pundit::Scopeを使うと、ロールや所有者ごとに表示を制限できます。」

1. Railsの認可とは?Punditが必要な理由

1. Railsの認可とは?Punditが必要な理由
1. Railsの認可とは?Punditが必要な理由

Railsの認可とは、「この人がこのデータを見たり操作してもよいか」を判断する仕組みです。例えば、会員制サイトで、管理者だけが全データを見られて、一般ユーザーは自分のデータだけ見られる、という状況を想像してください。

Punditは、Railsでよく使われる認可ライブラリのひとつで、ポリシーというルール集を使ってアクセス制御を行います。特に一覧画面では、データを取得する時点で絞り込むことがとても重要です。

2. Pundit::Scopeとは何かを超やさしく説明

2. Pundit::Scopeとは何かを超やさしく説明
2. Pundit::Scopeとは何かを超やさしく説明

Pundit::Scopeは、「一覧で取得してよいデータの範囲」を決める仕組みです。たとえるなら、図書館で「この人はこの棚まで入っていい」という境界線を引く役割です。

コントローラでindexアクションを実行するとき、すべてのレコードをそのまま表示すると、見せてはいけない情報まで見えてしまうことがあります。そこでScopeを使い、最初から安全なデータだけを取得します。

3. Pundit::Scopeの基本構造

3. Pundit::Scopeの基本構造
3. Pundit::Scopeの基本構造

Punditでは、モデルごとにポリシークラスを作ります。その中にScopeクラスを定義します。まずは基本形を見てみましょう。


class ArticlePolicy < ApplicationPolicy
  class Scope < Scope
    def resolve
      scope.all
    end
  end
end

scopeは、対象となるモデル(ここではArticle)を表します。resolveメソッドの戻り値が、一覧で表示されるデータになります。

4. 所有者別に一覧を絞り込む例

4. 所有者別に一覧を絞り込む例
4. 所有者別に一覧を絞り込む例

次に、「自分が作成したデータだけ見られる」ケースです。これは初心者が最初につまずきやすいポイントですが、とても大事です。


class ArticlePolicy < ApplicationPolicy
  class Scope < Scope
    def resolve
      scope.where(user_id: user.id)
    end
  end
end

ここでのuserは、ログインしているユーザーを意味します。このように書くことで、「自分が所有している記事だけ」が一覧に表示されます。

5. ロール別(管理者・一般ユーザー)で制御する

5. ロール別(管理者・一般ユーザー)で制御する
5. ロール別(管理者・一般ユーザー)で制御する

次はロール別の制御です。ロールとは「役割」のことです。管理者は全部見られて、一般ユーザーは自分の分だけ、という形がよくあります。


class ArticlePolicy < ApplicationPolicy
  class Scope < Scope
    def resolve
      if user.admin?
        scope.all
      else
        scope.where(user_id: user.id)
      end
    end
  end
end

admin?は、ユーザーが管理者かどうかを判定するメソッドです。条件分岐を使うことで、役割ごとに取得範囲を切り替えられます。

6. コントローラでPundit::Scopeを使う方法

6. コントローラでPundit::Scopeを使う方法
6. コントローラでPundit::Scopeを使う方法

ポリシーを書いただけでは動きません。コントローラでScopeを使ってデータを取得します。


class ArticlesController < ApplicationController
  def index
    @articles = policy_scope(Article)
  end
end

policy_scopeを使うことで、Pundit::Scopeのresolveが自動的に呼ばれ、安全な一覧だけが取得されます。

7. なぜ一覧での認可が重要なのか

7. なぜ一覧での認可が重要なのか
7. なぜ一覧での認可が重要なのか

一覧画面は、ユーザーが最初に目にする場所です。ここで制御を間違えると、本来見えないはずの情報が簡単に漏れてしまいます。

Pundit::Scopeを使うと、データベースから取得する時点で絞り込めるため、あとから隠すよりも安全で効率的です。これはRailsのセキュリティを守るうえでとても重要な考え方です。

8. CanCanCanとの違いを簡単に理解

8. CanCanCanとの違いを簡単に理解
8. CanCanCanとの違いを簡単に理解

Railsの認可ライブラリには、PunditのほかにCanCanCanもあります。CanCanCanは「できる・できない」をルールとしてまとめるのが特徴です。

一方Punditは、モデル単位で考えるため、Railsの構造と相性がよく、Scopeで一覧を安全に制御しやすいというメリットがあります。初心者でも、責務が分かりやすいのが特徴です。

カテゴリの一覧へ
新着記事
New1
Ruby
“すべてはオブジェクト”を体感!初心者向けRubyのオブジェクト指向入門【irbで学ぶ】
New2
Ruby
Rubyの標準入出力を完全ガイド!puts・print・pの違いとデバッグ活用法
New3
Ruby
Gemとは?RubyGemsとBundlerを初心者向けに完全解説!依存関係管理も図解でわかりやすく理解
New4
Ruby
Rubyの文字エンコーディング入門!UTF-8・マジックコメント・外部/内部エンコーディングを完全解説
人気記事
No.1
Java&Spring記事人気No1
Ruby
Rubyのreduceとinject入門!合計計算や集計を初心者向けに分かりやすく解説
No.2
Java&Spring記事人気No2
Ruby
Rubyの文字列エンコーディング完全ガイド!Encoding・force_encoding・encodeを初心者向け解説
No.3
Java&Spring記事人気No3
Ruby
Rubyの始め方ガイド:インストールから最初のHello Worldまで(Windows/Mac/Linux)
No.4
Java&Spring記事人気No4
データベース
PostgreSQLのWHERE句を徹底解説!初心者でもわかるSQLデータ抽出の基本
No.5
Java&Spring記事人気No5
Ruby
Rubyのfind/detect/find_indexを徹底解説!目的のデータを素早く探す方法
No.6
Java&Spring記事人気No6
Ruby
Rubyで比較演算子を完全解説!==・===・<=>・eql? の使い分け
No.7
Java&Spring記事人気No7
Ruby
Rubyのselect/reject/filterの使い方を完全解説!初心者向けの条件抽出レシピ
No.8
Java&Spring記事人気No8
データベース
PostgreSQLで順位付け!ROW_NUMBER関数の使い方を初心者向けに徹底解説