🧩

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 응답 포맷