【Ruby on Rails】 Serviceオブジェクト 実装方法と活用例

目次

Serviceオブジェクトとは

RailsにおけるServiceオブジェクトとは、特定のビジネスロジックを専用クラスとして切り出したものです。
コントローラーやモデルに複雑な処理を書くと、コードが煩雑になり、保守性が低下することがあります。
そこで登場するのがServiceオブジェクトです。

Serviceオブジェクトを利用すると、以下のような処理を一箇所にまとめられます。

  • 複数モデルにまたがる複雑な処理
  • 外部APIとの連携処理
  • データの一括更新や削除処理

これらの処理は、モデルやコントローラーに書くと肥大化を招きます。
専用のServiceクラスを作成して切り出すことで、コードの見通しが良くなります。
結果として、コードの可読性と保守性が向上するメリットがあるのです。

Serviceオブジェクトの利点

RailsでServiceオブジェクトを使う利点は、コードの整理や保守性向上にあります。
複雑な処理をモデルやコントローラーに書くと、以下の問題が起こります。

  • モデルが肥大化してしまう
  • コントローラーの役割が曖昧になる
  • テストが書きにくくなる

そこでServiceオブジェクトを使うと、以下のメリットが得られます。

  • モデルやコントローラーがシンプルになる
  • 各クラスの役割が明確になる
  • テストを容易に書けるようになる

実際に導入すると、チーム内でコードの役割が明確になり、開発効率も上がるでしょう。
特に規模が大きいプロジェクトほど、その効果を実感できます。

Serviceオブジェクト導入手順

RailsでServiceオブジェクトを導入する手順を解説します。
導入は非常にシンプルです。

①ディレクトリを作成する

まず、app/servicesという専用フォルダを作成します。

mkdir app/services

②Serviceクラスを作成する

次に、具体的な処理を行うServiceクラスを作成します。
例えばユーザーの一括作成処理を行う場合は以下のようになります。

# app/services/user_bulk_creator.rb
class UserBulkCreator
  def initialize(user_params_array)
    @user_params_array = user_params_array
  end

  def call
    User.transaction do
      @user_params_array.each do |user_params|
        User.create!(user_params)
      end
    end
    true
  rescue ActiveRecord::RecordInvalid => e
    Rails.logger.error "ユーザー作成エラー: #{e.message}"
    false
  end
end

③コントローラーから呼び出す

コントローラーからは、以下のように呼び出します。

def bulk_create
  service = UserBulkCreator.new(params[:users])
  if service.call
    redirect_to users_path, notice: 'ユーザーを一括作成しました。'
  else
    render :new, alert: 'ユーザー作成に失敗しました。'
  end
end

このように簡単な手順で導入できます。
ぜひ試してみてください。

実践的な実装コード例

ここでは、外部APIと連携するServiceオブジェクトの実践例を紹介します。
具体的には、外部APIからデータを取得してレコードを作成する処理です。

コード例

# app/services/external_api_importer.rb
require 'net/http'
require 'json'

class ExternalApiImporter
  API_ENDPOINT = 'https://api.example.com/data'

  def initialize
    @uri = URI(API_ENDPOINT)
  end

  def call
    response = Net::HTTP.get(@uri)
    data = JSON.parse(response)

    data.each do |item|
      ModelName.create!(
        title: item['title'],
        description: item['description']
      )
    end
    true
  rescue JSON::ParserError, ActiveRecord::RecordInvalid => e
    Rails.logger.error "インポートエラー: #{e.message}"
    false
  end
end

ポイント

  • 外部APIとの連携処理を一箇所にまとめる
  • エラー処理を明確にしてログを残す
  • コントローラーやモデルにAPI処理を書かない

これにより、コードが整理され、保守性が向上します。

Service活用場面と事例

RailsのServiceオブジェクトはどのような場面で活用できるでしょうか?
代表的な活用シーンを以下にまとめました。

  • 複数モデルにまたがる処理(注文処理、ユーザー登録処理など)
  • 外部APIとの連携(天気情報取得、Twitter連携など)
  • バッチ処理や一括更新処理(ユーザー一括登録、メール送信処理など)

例えば、ECサイトで注文を受ける処理は、注文情報の作成、在庫管理、決済処理など、複数モデルにまたがります。
このような場合、Serviceオブジェクトを導入するとコードが整理されます。

実際の開発現場でも、多くの開発者がServiceオブジェクトを活用し、コードの保守性を高めています。
ぜひ積極的に活用しましょう。

効果的に活用するポイント

Serviceオブジェクトを効果的に活用するには、以下のポイントを押さえることが大切です。

  • 一つのServiceオブジェクトは一つの責務に絞る
  • 名前を明確に付け、処理内容を分かりやすくする
  • Serviceオブジェクト内で直接パラメーターを取得せず、初期化時に渡すよう統一する

さらに、Serviceオブジェクトは積極的にテストを書きましょう。
RSpecなどを使って単体テストを行うことで、品質を高めることが可能です。

RSpecの公式サイト

まとめと注意すべき点

今回はRailsのServiceオブジェクトについて解説しました。
Serviceオブジェクトを使うことで、コードの保守性や可読性が向上します。

最後に注意すべきポイントをまとめます。

  • Serviceオブジェクトを作りすぎない(本当に複雑な処理のみ導入する)
  • 命名ルールを統一し、処理内容を分かりやすくする
  • Service内で例外処理やログ出力を適切に行う

これらのポイントを意識して導入すれば、Railsアプリケーションの品質が劇的に改善します。
ぜひ実際のプロジェクトで活用してみてください。

未経験からエンジニアへ転職!おすすめの転職サービスはこちら

「未経験だけどエンジニアになりたい…」「IT業界に興味があるけど、どこから始めるべきかわからない…」
そんな方におすすめなのが、プログラミングスクールを活用した転職活動です。
実績豊富なスクールを利用すれば、未経験からでもエンジニアとしての転職がぐっと近づきます!

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次