0
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?

📘 サービスオブジェクトによるRuby on Railsのリファクタリングチュートリアル

Posted at

Dev Refactor.png

このチュートリアルでは、ClinicSync プロジェクトで行った2つのリファクタリングについて解説します。このアプリケーションは、私のRuby on Rails MBAの一環として開発された医療クリニック管理システムです。目的は、サービスオブジェクト(Service Objects) を活用して、コードの可読性、保守性、拡張性を向上させることです。

サービスオブジェクトとは?

サービスオブジェクト は、モデルやコントローラー、ビューに属さない ビジネスロジックを整理するためのシンプルなクラス です。
これは、単一責任の原則(Single Responsibility Principle, SRP) を実践する方法の1つであり、システムの各部分に明確な役割を与えることができます。


サービスオブジェクトを使うべきタイミング

次のような場合にサービスオブジェクトの導入を検討しましょう:

  • ロジックが複雑でコントローラーに収まりきらないとき
  • 機能が特定のモデルに自然に属さないとき
  • 同じロジックを複数箇所で再利用したいとき
  • よりクリーンでテストしやすいコードを目指したいとき

サービスオブジェクトの基本構造

class ExampleService
  def self.call(params)
    new(params).call
  end

  def initialize(params)
    @params = params
  end

  def call
    # メインのロジックをここに記述
  end
end

リファクタリング①:AuthorizeUser サービス

目的:

コントローラーに繰り返し書かれていたユーザータイプの判定処理を外部化する。

リファクタリング前:

def require_admin
  unless user_signed_in? && current_user.is_a?(Admin)
    redirect_to root_path, alert: "You are not authorized to access this page."
  end
end

リファクタリング後:

def require_admin
  unless user_signed_in? && AuthorizeUser.call(current_user, Admin)
    redirect_to root_path, alert: "You are not authorized to access this page."
  end
end

作成されたサービス:

class AuthorizeUser
  def self.call(user, user_type)
    user.is_a?(user_type)
  end
end

メリット:

  • ロジックの重複排除(DRY)
  • 保守性の向上
  • クリーンで再利用可能なコード

リファクタリング②:AuthenticateUser サービス

目的:

ユーザー認証処理を SessionsController から分離する。

リファクタリング前:

if (user = User.authenticate_by(params.permit(:email_address, :password)))
  start_new_session_for user
  redirect_to home_path_for(user), notice: "Logged in successfully."
else
  redirect_to new_session_path, alert: "Try another email address or password."
end

リファクタリング後:

user = AuthenticateUser.call(params[:email_address], params[:password])

if user
  start_new_session_for user
  redirect_to home_path_for(user), notice: "Logged in successfully."
else
  redirect_to new_session_path, alert: "Try another email address or password."
end

作成されたサービス:

class AuthenticateUser
  def self.call(email_address, password)
    User.authenticate_by(email_address: email_address, password: password)
  end
end

メリット:

  • コントローラーの簡素化
  • ソーシャルログインや二要素認証などの拡張が容易
  • 責務の明確な分離

まとめ

この2つの小さなサービスオブジェクトにより、プロジェクトは:

  • よりクリーンに
  • テストしやすく
  • 拡張しやすくなった

サービスオブジェクトは、クリーンコードを実現し、Railsアプリケーションを将来の拡張に備えるための強力な手法です。


作成者: [レオナルド・フラゴーゾ]

0
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
0
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?