Railsのデザインパターンでリファクタリング

RailsはMVC(Model-View-Controller)を前提としたフレームワークですが、アプリケーションが大きくなると

#1. リファクタリング前の問題

例えば、ユーザー登録処理を以下のようにコントローラーでまとめている場合を考えます。

# app/controllers/users_controller.rb def create @user = User.new(user_params) if @user.save # 登録成功後の処理 UserMailer.welcome_email(@user).deliver_later AccountCreationService.new(@user).create_default_account redirect_to root_path, notice: '登録完了' else render :new end end

問題点

  • コントローラーが肥大化している
  • メール送信やアカウント作成など、ビジネスロジックが分散している
  • テストが書きにくい

#2. Service Objectでリファクタリング

コントローラーの処理を Service Object に切り出すことで、責務を整理できます。

# app/services/user_registration_service.rb class UserRegistrationService def initialize(params) @params = params end def call user = User.new(@params) return false unless user.save send_welcome_email(user) create_default_account(user) true end private def send_welcome_email(user) UserMailer.welcome_email(user).deliver_later end def create_default_account(user) AccountCreationService.new(user).create_default_account end end

コントローラーの変更後

def create if UserRegistrationService.new(user_params).call redirect_to root_path, notice: '登録完了' else render :new end end
  • コントローラーは リクエストの受け取りとレスポンス返却だけ に集中
  • ユーザー登録のビジネスロジックは Service Object に集約

#3. Presenter / Decoratorでビューを整理

ビューでの表示ロジックもモデルから分離できます。

例:ユーザーのフルネーム表示

# app/decorators/user_decorator.rb class UserDecorator < SimpleDelegator def display_name "#{first_name} #{last_name}".strip end end

コントローラーでの利用

def show @user = UserDecorator.new(User.find(params[:id])) end
  • ビューでは @user.display_name で整形済みの名前を取得できる
  • モデルやビューがスッキリして、変更に強いコードになる

#4. Observerで副作用処理を分離

モデルに書かれていた副作用処理(メール送信など)も Observer パターンで整理できます。

# app/models/user.rb class User < ApplicationRecord after_create :notify_registration private def notify_registration UserMailer.welcome_email(self).deliver_later end end
  • モデルの主要ロジックと副作用処理を分離
  • Service Object と組み合わせるとさらに整理される

#5. リファクタリングの効果

BeforeAfter
コントローラーが肥大化コントローラーは処理呼び出しのみ
モデルに複雑なビジネスロジックService Object に集約
ビューで整形処理Presenter/Decorator に集約
副作用処理がモデルに混在Observer で分離
  • テストが書きやすくなる
  • 再利用性が向上
  • 変更に強い構造 になる

#6. まとめ

Railsでデザインパターンを使ったリファクタリングは、以下のステップが基本です。

  1. コントローラーの肥大化を確認 → Service Object で切り出す
  2. ビューの表示ロジックを確認 → Presenter / Decorator で整理
  3. モデルの副作用処理を確認 → Observer で分離
  4. ファクトリーパターンでテストデータを整理

💡 ポイント

  • 小規模アプリでは必須ではないが、中規模以上で効果絶大
  • 「責務を1つにまとめる」 がリファクタリング成功のコツ

タグ一覧