💨
FormとServiceの違い
「フォーム(Form Object)」と「サービス(Service Object)」は、どちらもRailsのモデルを肥大化させないために使われる手法ですが、その目的と役割が明確に異なります。
簡単に言えば、**フォームは「データの入力」**を扱い、**サービスは「ビジネスロジックの実行」**を扱います。
フォームオブジェクト(Form Object)
フォームオブジェクトは、ユーザーからの入力データに特化した「仲介役」です。
-
目的:
- 複数のモデルにまたがるデータを一つのフォームで受け付けたいとき。
- データベースに保存しない、フォーム専用のバリデーションを定義したいとき(例:パスワードと確認用パスワードの一致)。
-
役割:
-
入力の統合: 複数のモデル(例:
UserとProfile)の属性を一つのオブジェクトにまとめます。 - バリデーション: モデルのバリデーションとは別に、フォームの入力値チェックを行います。
-
入力の統合: 複数のモデル(例:
-
使用例:
- 会員登録フォームで、
UserモデルとProfileモデルの情報を同時に受け取る。 - 複雑な検索フォームで、複数の検索条件をまとめて処理する。
- 会員登録フォームで、
-
結論: フォームオブジェクトは、ユーザーインターフェース(フォーム)の裏側にあるデータの受け皿であり、その正当性を検証する役割を担います。
サービスオブジェクト(Service Object)
サービスオブジェクトは、複数のモデルや外部サービスを操作する「ビジネスロジックの実行者」です。
-
目的:
- 複数のモデルや外部サービスにまたがる複雑なビジネスフローを実行したいとき。
- コントローラーやモデルから、ビジネスロジックを完全に分離したいとき。
-
役割:
-
ロジックの集約: 「注文処理」「ユーザーの招待」「データのインポート」といった、一連の手続きを一つのメソッド(例:
call)にまとめます。 - トランザクション管理: 複数のデータベース操作を安全に行うために、トランザクションを管理します。
-
ロジックの集約: 「注文処理」「ユーザーの招待」「データのインポート」といった、一連の手続きを一つのメソッド(例:
-
使用例:
- ECサイトの「注文確定」処理で、
Orderの作成、Productの在庫減少、Stripeでの決済、Emailでの通知をまとめて行う。 - 特定の条件を満たしたユーザーにバッジを付与し、通知を送る一連の処理。
- ECサイトの「注文確定」処理で、
-
結論: サービスオブジェクトは、特定のビジネスアクションを実行する責任を持ち、そのロジックをカプセル化することで、コントローラーやモデルをシンプルに保ちます。
まとめと使い分け
| 項目 | フォームオブジェクト | サービスオブジェクト |
|---|---|---|
| 主な目的 | 入力データの受け渡し | ビジネスロジックの実行 |
| 対象 | フォームの入力値 | 複数のモデルや外部サービス |
| 使いたい時 | フォームの入力値が複雑なとき | 実行する処理が複雑なとき |
| 結果 | フォームのバリデーション結果 | 処理の成功・失敗 |
どちらもモデルをきれいに保つための強力な手法ですが、何が目的かを明確にすることで使い分けが簡単になります。
入力データの整理が必要ならフォーム、複雑な処理の実行が必要ならサービス、と考えると良いでしょう。
Discussion