🧩

Controller Concerns

複数のControllerで共有するモジュール

ConcernはRubyのActiveSupport::Concernを活用したモジュールパターンで、複数のController(またはModel)で共通機能を共有する際に使用します。

# app/controllers/concerns/paginatable.rb
module Paginatable
  extend ActiveSupport::Concern

  included do
    helper_method :page, :per_page
  end

  private

  def page
    (params[:page] || 1).to_i
  end

  def per_page
    (params[:per_page] || 20).to_i
  end

  def paginate(scope)
    scope.offset((page - 1) * per_page).limit(per_page)
  end
end

使用: include Paginatable

includedブロック: include時に実行(before_action、helper_method等)
class_methodsブロック: クラスメソッド定義

Concernは「横断的関心事」(cross-cutting concern)に適しています。認証、ロギング、ページネーションのように複数コントローラにまたがる機能をきれいに分離します。

キーポイント

1

app/controllers/concerns/にモジュールファイル生成

2

extend ActiveSupport::ConcernでConcern宣言

3

includedブロックにbefore_action、helper_method等を設定

4

Controllerでinclude ModuleNameで使用

5

class_methodsブロックでクラスメソッドも定義可能

6

Model Concernはapp/models/concerns/に同じパターンで生成

メリット

  • コード再利用の最大化(DRY)
  • Controller/Modelファイルがすっきりする
  • Rubyモジュールシステム活用 → テスト容易
  • included/class_methodsで構造的

デメリット

  • 乱用するとコード追跡が困難
  • 複数Concernをinclude時メソッド衝突の可能性
  • 継承より優先順位の把握が複雑
  • Concernが大きすぎると別サービスへの分離が必要

ユースケース

認証/権限モジュール ページネーション 検索機能 監査ロギング APIレスポンスフォーマット