💨

FormとServiceの違い

に公開

「フォーム(Form Object)」と「サービス(Service Object)」は、どちらもRailsのモデルを肥大化させないために使われる手法ですが、その目的と役割が明確に異なります。

簡単に言えば、**フォームは「データの入力」**を扱い、**サービスは「ビジネスロジックの実行」**を扱います。


フォームオブジェクト(Form Object)

フォームオブジェクトは、ユーザーからの入力データに特化した「仲介役」です。

  • 目的:

    • 複数のモデルにまたがるデータを一つのフォームで受け付けたいとき。
    • データベースに保存しない、フォーム専用のバリデーションを定義したいとき(例:パスワードと確認用パスワードの一致)。
  • 役割:

    • 入力の統合: 複数のモデル(例:UserとProfile)の属性を一つのオブジェクトにまとめます。
    • バリデーション: モデルのバリデーションとは別に、フォームの入力値チェックを行います。
  • 使用例:

    • 会員登録フォームで、UserモデルとProfileモデルの情報を同時に受け取る。
    • 複雑な検索フォームで、複数の検索条件をまとめて処理する。
  • 結論: フォームオブジェクトは、ユーザーインターフェース(フォーム)の裏側にあるデータの受け皿であり、その正当性を検証する役割を担います。


サービスオブジェクト(Service Object)

サービスオブジェクトは、複数のモデルや外部サービスを操作する「ビジネスロジックの実行者」です。

  • 目的:

    • 複数のモデルや外部サービスにまたがる複雑なビジネスフローを実行したいとき。
    • コントローラーやモデルから、ビジネスロジックを完全に分離したいとき。
  • 役割:

    • ロジックの集約: 「注文処理」「ユーザーの招待」「データのインポート」といった、一連の手続きを一つのメソッド(例:call)にまとめます。
    • トランザクション管理: 複数のデータベース操作を安全に行うために、トランザクションを管理します。
  • 使用例:

    • ECサイトの「注文確定」処理で、Orderの作成、Productの在庫減少、Stripeでの決済、Emailでの通知をまとめて行う。
    • 特定の条件を満たしたユーザーにバッジを付与し、通知を送る一連の処理。
  • 結論: サービスオブジェクトは、特定のビジネスアクションを実行する責任を持ち、そのロジックをカプセル化することで、コントローラーやモデルをシンプルに保ちます。


まとめと使い分け

項目 フォームオブジェクト サービスオブジェクト
主な目的 入力データの受け渡し ビジネスロジックの実行
対象 フォームの入力値 複数のモデルや外部サービス
使いたい時 フォームの入力値が複雑なとき 実行する処理が複雑なとき
結果 フォームのバリデーション結果 処理の成功・失敗

どちらもモデルをきれいに保つための強力な手法ですが、何が目的かを明確にすることで使い分けが簡単になります。
入力データの整理が必要ならフォーム、複雑な処理の実行が必要ならサービス、と考えると良いでしょう。

Discussion